|
@@ -138,6 +138,8 @@
|
|
|
#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>
|
|
|
|
|
@@ -2345,6 +2347,34 @@ static int _shutdown(struct omap_hwmod *oh)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 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;
|