aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 93f213b6a784..d25a95fe9921 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -139,6 +139,8 @@
139#include <linux/slab.h> 139#include <linux/slab.h>
140#include <linux/bootmem.h> 140#include <linux/bootmem.h>
141#include <linux/cpu.h> 141#include <linux/cpu.h>
142#include <linux/of.h>
143#include <linux/of_address.h>
142 144
143#include <asm/system_misc.h> 145#include <asm/system_misc.h>
144 146
@@ -2350,6 +2352,34 @@ static int _shutdown(struct omap_hwmod *oh)
2350} 2352}
2351 2353
2352/** 2354/**
2355 * of_dev_hwmod_lookup - look up needed hwmod from dt blob
2356 * @np: struct device_node *
2357 * @oh: struct omap_hwmod *
2358 *
2359 * Parse the dt blob and find out needed hwmod. Recursive function is
2360 * implemented to take care hierarchical dt blob parsing.
2361 * Return: The device node on success or NULL on failure.
2362 */
2363static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
2364 struct omap_hwmod *oh)
2365{
2366 struct device_node *np0 = NULL, *np1 = NULL;
2367 const char *p;
2368
2369 for_each_child_of_node(np, np0) {
2370 if (of_find_property(np0, "ti,hwmods", NULL)) {
2371 p = of_get_property(np0, "ti,hwmods", NULL);
2372 if (!strcmp(p, oh->name))
2373 return np0;
2374 np1 = of_dev_hwmod_lookup(np0, oh);
2375 if (np1)
2376 return np1;
2377 }
2378 }
2379 return NULL;
2380}
2381
2382/**
2353 * _init_mpu_rt_base - populate the virtual address for a hwmod 2383 * _init_mpu_rt_base - populate the virtual address for a hwmod
2354 * @oh: struct omap_hwmod * to locate the virtual address 2384 * @oh: struct omap_hwmod * to locate the virtual address
2355 * 2385 *
@@ -2361,7 +2391,8 @@ static int _shutdown(struct omap_hwmod *oh)
2361static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) 2391static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
2362{ 2392{
2363 struct omap_hwmod_addr_space *mem; 2393 struct omap_hwmod_addr_space *mem;
2364 void __iomem *va_start; 2394 void __iomem *va_start = NULL;
2395 struct device_node *np;
2365 2396
2366 if (!oh) 2397 if (!oh)
2367 return; 2398 return;
@@ -2375,10 +2406,18 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
2375 if (!mem) { 2406 if (!mem) {
2376 pr_debug("omap_hwmod: %s: no MPU register target found\n", 2407 pr_debug("omap_hwmod: %s: no MPU register target found\n",
2377 oh->name); 2408 oh->name);
2378 return; 2409
2410 /* Extract the IO space from device tree blob */
2411 if (!of_have_populated_dt())
2412 return;
2413
2414 np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
2415 if (np)
2416 va_start = of_iomap(np, 0);
2417 } else {
2418 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
2379 } 2419 }
2380 2420
2381 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
2382 if (!va_start) { 2421 if (!va_start) {
2383 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); 2422 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
2384 return; 2423 return;
@@ -2410,7 +2449,8 @@ static int __init _init(struct omap_hwmod *oh, void *data)
2410 if (oh->_state != _HWMOD_STATE_REGISTERED) 2449 if (oh->_state != _HWMOD_STATE_REGISTERED)
2411 return 0; 2450 return 0;
2412 2451
2413 _init_mpu_rt_base(oh, NULL); 2452 if (oh->class->sysc)
2453 _init_mpu_rt_base(oh, NULL);
2414 2454
2415 r = _init_clocks(oh, NULL); 2455 r = _init_clocks(oh, NULL);
2416 if (r < 0) { 2456 if (r < 0) {