ARM: OMAP2+: hwmod: extract module address space from DT blob
authorSantosh Shilimkar <santosh.shilimkar@ti.com>
Mon, 21 Jan 2013 13:10:57 +0000 (18:40 +0530)
committerBenoit Cousson <benoit.cousson@linaro.org>
Mon, 8 Apr 2013 22:21:21 +0000 (00:21 +0200)
Patch adds the code for extracting the module ocp address space
from device tree blob in case the hwmod address space look up fails.

The idea is to remove the address space data from hwmod and extract
it from DT blob.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Benoit Cousson <benoit.cousson@linaro.org>
arch/arm/mach-omap2/omap_hwmod.c

index e5cafed..ff72970 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/system_misc.h>
 
@@ -2346,6 +2348,34 @@ static int _shutdown(struct omap_hwmod *oh)
 }
 
 /**
+ * of_dev_hwmod_lookup - look up needed hwmod from dt blob
+ * @np: struct device_node *
+ * @oh: struct omap_hwmod *
+ *
+ * Parse the dt blob and find out needed hwmod. Recursive function is
+ * implemented to take care hierarchical dt blob parsing.
+ * Return: The device node on success or NULL on failure.
+ */
+static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
+                                               struct omap_hwmod *oh)
+{
+       struct device_node *np0 = NULL, *np1 = NULL;
+       const char *p;
+
+       for_each_child_of_node(np, np0) {
+               if (of_find_property(np0, "ti,hwmods", NULL)) {
+                       p = of_get_property(np0, "ti,hwmods", NULL);
+                       if (!strcmp(p, oh->name))
+                               return np0;
+                       np1 = of_dev_hwmod_lookup(np0, oh);
+                       if (np1)
+                               return np1;
+               }
+       }
+       return NULL;
+}
+
+/**
  * _init_mpu_rt_base - populate the virtual address for a hwmod
  * @oh: struct omap_hwmod * to locate the virtual address
  *
@@ -2357,7 +2387,8 @@ static int _shutdown(struct omap_hwmod *oh)
 static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
 {
        struct omap_hwmod_addr_space *mem;
-       void __iomem *va_start;
+       void __iomem *va_start = NULL;
+       struct device_node *np;
 
        if (!oh)
                return;
@@ -2371,10 +2402,18 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
        if (!mem) {
                pr_debug("omap_hwmod: %s: no MPU register target found\n",
                         oh->name);
-               return;
+
+               /* Extract the IO space from device tree blob */
+               if (!of_have_populated_dt())
+                       return;
+
+               np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
+               if (np)
+                       va_start = of_iomap(np, 0);
+       } else {
+               va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
        }
 
-       va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
        if (!va_start) {
                pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
                return;