drivers: mfd: refactor the vexpress config bridge API
authorPawel Moll <pawel.moll@arm.com>
Thu, 6 Jun 2013 09:59:22 +0000 (10:59 +0100)
committerJon Medhurst <tixy@linaro.org>
Mon, 1 Jul 2013 10:04:57 +0000 (11:04 +0100)
The introduction of Serial Power Controller (SPC) requires the vexpress
config interface to change slightly since the SPC memory mapped interface
can be used as configuration bus but also for operating points
programming and retrieval. The helper that allocates the bridge functions
requires an additional parameter allowing to request component specific
functions that need not be initialized through device tree bindings but
just using simple look-up and statically defined constants.

This patch introduces the necessary changes to the vexpress config layer
to cater for the new vexpress bridge interface requirements.

Cc: Samuel Ortiz <sameo@linux.intel.com>
Cc: Achin Gupta <achin.gupta@arm.com>
Cc: Sudeep KarkadaNagesha <Sudeep.KarkadaNagesha@arm.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Cc: Amit Kucheria <amit.kucheria@linaro.org>
Cc: Jon Medhurst <tixy@linaro.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
Acked-by: Nicolas Pitre <nico@linaro.org>
drivers/mfd/vexpress-config.c
drivers/mfd/vexpress-sysreg.c
include/linux/vexpress.h

index 84ce6b9daa3dea13b2adf8d07d907fb128d1175c..1af2b0e0182ffb338466e3a0abbb1990e66bdcdf 100644 (file)
@@ -86,29 +86,13 @@ void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge)
 }
 EXPORT_SYMBOL(vexpress_config_bridge_unregister);
 
-
-struct vexpress_config_func {
-       struct vexpress_config_bridge *bridge;
-       void *func;
-};
-
-struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
-               struct device_node *node)
+static struct vexpress_config_bridge *
+               vexpress_config_bridge_find(struct device_node *node)
 {
-       struct device_node *bridge_node;
-       struct vexpress_config_func *func;
        int i;
+       struct vexpress_config_bridge *res = NULL;
+       struct device_node *bridge_node = of_node_get(node);
 
-       if (WARN_ON(dev && node && dev->of_node != node))
-               return NULL;
-       if (dev && !node)
-               node = dev->of_node;
-
-       func = kzalloc(sizeof(*func), GFP_KERNEL);
-       if (!func)
-               return NULL;
-
-       bridge_node = of_node_get(node);
        while (bridge_node) {
                const __be32 *prop = of_get_property(bridge_node,
                                "arm,vexpress,config-bridge", NULL);
@@ -129,13 +113,46 @@ struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
 
                if (test_bit(i, vexpress_config_bridges_map) &&
                                bridge->node == bridge_node) {
-                       func->bridge = bridge;
-                       func->func = bridge->info->func_get(dev, node);
+                       res = bridge;
                        break;
                }
        }
        mutex_unlock(&vexpress_config_bridges_mutex);
 
+       return res;
+}
+
+
+struct vexpress_config_func {
+       struct vexpress_config_bridge *bridge;
+       void *func;
+};
+
+struct vexpress_config_func *__vexpress_config_func_get(
+               struct vexpress_config_bridge *bridge,
+               struct device *dev,
+               struct device_node *node,
+               const char *id)
+{
+       struct vexpress_config_func *func;
+
+       if (WARN_ON(dev && node && dev->of_node != node))
+               return NULL;
+       if (dev && !node)
+               node = dev->of_node;
+
+       if (!bridge)
+               bridge = vexpress_config_bridge_find(node);
+       if (!bridge)
+               return NULL;
+
+       func = kzalloc(sizeof(*func), GFP_KERNEL);
+       if (!func)
+               return NULL;
+
+       func->bridge = bridge;
+       func->func = bridge->info->func_get(dev, node, id);
+
        if (!func->func) {
                of_node_put(node);
                kfree(func);
index 96a020b1dcd14a9321a1358a6dd420c1522e2f60..d2599aa26f915e3ef872c1e263f78a59ad967051 100644 (file)
@@ -165,7 +165,7 @@ static u32 *vexpress_sysreg_config_data;
 static int vexpress_sysreg_config_tries;
 
 static void *vexpress_sysreg_config_func_get(struct device *dev,
-               struct device_node *node)
+               struct device_node *node, const char *id)
 {
        struct vexpress_sysreg_config_func *config_func;
        u32 site;
index ea7168a680810dba82505afd827ff4909bf5130e..89152673a472f5fa2e47e92304f8ebd67be622d1 100644 (file)
@@ -68,7 +68,8 @@
  */
 struct vexpress_config_bridge_info {
        const char *name;
-       void *(*func_get)(struct device *dev, struct device_node *node);
+       void *(*func_get)(struct device *dev, struct device_node *node,
+                         const char *id);
        void (*func_put)(void *func);
        int (*func_exec)(void *func, int offset, bool write, u32 *data);
 };
@@ -87,12 +88,17 @@ void vexpress_config_complete(struct vexpress_config_bridge *bridge,
 
 struct vexpress_config_func;
 
-struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
-               struct device_node *node);
+struct vexpress_config_func *__vexpress_config_func_get(
+               struct vexpress_config_bridge *bridge,
+               struct device *dev,
+               struct device_node *node,
+               const char *id);
+#define vexpress_config_func_get(bridge, id) \
+               __vexpress_config_func_get(bridge, NULL, NULL, id)
 #define vexpress_config_func_get_by_dev(dev) \
-               __vexpress_config_func_get(dev, NULL)
+               __vexpress_config_func_get(NULL, dev, NULL, NULL)
 #define vexpress_config_func_get_by_node(node) \
-               __vexpress_config_func_get(NULL, node)
+               __vexpress_config_func_get(NULL, NULL, node, NULL)
 void vexpress_config_func_put(struct vexpress_config_func *func);
 
 /* Both may sleep! */