aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorKevin Hilman <khilman@linaro.org>2013-12-09 18:38:00 -0500
committerKevin Hilman <khilman@linaro.org>2013-12-09 18:38:41 -0500
commited16c8c50e26df3c16e40d35c9a4c0e9f032656c (patch)
treef268748e4bd3a6ceb08b7a7a70fb86c4dfce0e02 /arch/arm/mach-omap2/omap_hwmod.c
parent8ae19ec3356901bafa64816d9ea9378896f8979c (diff)
parentf2e2c9d9b4087b74eb9e00d8dfac148354cb0b71 (diff)
Merge tag 'omap-for-v3.13/yet-more-dt-regressions-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into fixes
A rather big fix for a regression where we have dropped omap4 hwmod data earlier but are not initializing it from device tree. In addition to this fix we eventually also be fix the issues in the .dts files and drivers, but that's too intrusive for the -rc cycle and must be done later on. Also a fix for a regression where we now are wrongly trying to initialize devices on secure omaps like n900 and n9* when booted using device tree. We need to set aes, sham and timer12 to disabled mode for secure devices as they are claimed by the firmware running in the secure mode. And two more legacy booting vs device tree based booting fixes for am3517 that I did not notice earlier until Nishant Menon reported these to me few days ago. With these we're good to go having v3.13 working both for legacy booting and device tree based booting, and we can then go ahed and drop the legacy booting for mach-omap2 for v3.14. * tag 'omap-for-v3.13/yet-more-dt-regressions-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (494 commits) ARM: dts: Fix booting for secure omaps ARM: OMAP2+: Fix the machine entry for am3517 ARM: dts: Fix missing entries for am3517 ARM: OMAP2+: Fix overwriting hwmod data with data from device tree +Linux 3.13-rc3
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c98
1 files changed, 78 insertions, 20 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index e3f0ecaf87dd..ee655dab672f 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2326,38 +2326,80 @@ static int _shutdown(struct omap_hwmod *oh)
2326 return 0; 2326 return 0;
2327} 2327}
2328 2328
2329static int of_dev_find_hwmod(struct device_node *np,
2330 struct omap_hwmod *oh)
2331{
2332 int count, i, res;
2333 const char *p;
2334
2335 count = of_property_count_strings(np, "ti,hwmods");
2336 if (count < 1)
2337 return -ENODEV;
2338
2339 for (i = 0; i < count; i++) {
2340 res = of_property_read_string_index(np, "ti,hwmods",
2341 i, &p);
2342 if (res)
2343 continue;
2344 if (!strcmp(p, oh->name)) {
2345 pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n",
2346 np->name, i, oh->name);
2347 return i;
2348 }
2349 }
2350
2351 return -ENODEV;
2352}
2353
2329/** 2354/**
2330 * of_dev_hwmod_lookup - look up needed hwmod from dt blob 2355 * of_dev_hwmod_lookup - look up needed hwmod from dt blob
2331 * @np: struct device_node * 2356 * @np: struct device_node *
2332 * @oh: struct omap_hwmod * 2357 * @oh: struct omap_hwmod *
2358 * @index: index of the entry found
2359 * @found: struct device_node * found or NULL
2333 * 2360 *
2334 * Parse the dt blob and find out needed hwmod. Recursive function is 2361 * Parse the dt blob and find out needed hwmod. Recursive function is
2335 * implemented to take care hierarchical dt blob parsing. 2362 * implemented to take care hierarchical dt blob parsing.
2336 * Return: The device node on success or NULL on failure. 2363 * Return: Returns 0 on success, -ENODEV when not found.
2337 */ 2364 */
2338static struct device_node *of_dev_hwmod_lookup(struct device_node *np, 2365static int of_dev_hwmod_lookup(struct device_node *np,
2339 struct omap_hwmod *oh) 2366 struct omap_hwmod *oh,
2367 int *index,
2368 struct device_node **found)
2340{ 2369{
2341 struct device_node *np0 = NULL, *np1 = NULL; 2370 struct device_node *np0 = NULL;
2342 const char *p; 2371 int res;
2372
2373 res = of_dev_find_hwmod(np, oh);
2374 if (res >= 0) {
2375 *found = np;
2376 *index = res;
2377 return 0;
2378 }
2343 2379
2344 for_each_child_of_node(np, np0) { 2380 for_each_child_of_node(np, np0) {
2345 if (of_find_property(np0, "ti,hwmods", NULL)) { 2381 struct device_node *fc;
2346 p = of_get_property(np0, "ti,hwmods", NULL); 2382 int i;
2347 if (!strcmp(p, oh->name)) 2383
2348 return np0; 2384 res = of_dev_hwmod_lookup(np0, oh, &i, &fc);
2349 np1 = of_dev_hwmod_lookup(np0, oh); 2385 if (res == 0) {
2350 if (np1) 2386 *found = fc;
2351 return np1; 2387 *index = i;
2388 return 0;
2352 } 2389 }
2353 } 2390 }
2354 return NULL; 2391
2392 *found = NULL;
2393 *index = 0;
2394
2395 return -ENODEV;
2355} 2396}
2356 2397
2357/** 2398/**
2358 * _init_mpu_rt_base - populate the virtual address for a hwmod 2399 * _init_mpu_rt_base - populate the virtual address for a hwmod
2359 * @oh: struct omap_hwmod * to locate the virtual address 2400 * @oh: struct omap_hwmod * to locate the virtual address
2360 * @data: (unused, caller should pass NULL) 2401 * @data: (unused, caller should pass NULL)
2402 * @index: index of the reg entry iospace in device tree
2361 * @np: struct device_node * of the IP block's device node in the DT data 2403 * @np: struct device_node * of the IP block's device node in the DT data
2362 * 2404 *
2363 * Cache the virtual address used by the MPU to access this IP block's 2405 * Cache the virtual address used by the MPU to access this IP block's
@@ -2368,7 +2410,7 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
2368 * -ENXIO on absent or invalid register target address space. 2410 * -ENXIO on absent or invalid register target address space.
2369 */ 2411 */
2370static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, 2412static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
2371 struct device_node *np) 2413 int index, struct device_node *np)
2372{ 2414{
2373 struct omap_hwmod_addr_space *mem; 2415 struct omap_hwmod_addr_space *mem;
2374 void __iomem *va_start = NULL; 2416 void __iomem *va_start = NULL;
@@ -2390,13 +2432,17 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
2390 if (!np) 2432 if (!np)
2391 return -ENXIO; 2433 return -ENXIO;
2392 2434
2393 va_start = of_iomap(np, oh->mpu_rt_idx); 2435 va_start = of_iomap(np, index + oh->mpu_rt_idx);
2394 } else { 2436 } else {
2395 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); 2437 va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
2396 } 2438 }
2397 2439
2398 if (!va_start) { 2440 if (!va_start) {
2399 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); 2441 if (mem)
2442 pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
2443 else
2444 pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n",
2445 oh->name, index, np->full_name);
2400 return -ENXIO; 2446 return -ENXIO;
2401 } 2447 }
2402 2448
@@ -2422,17 +2468,29 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
2422 */ 2468 */
2423static int __init _init(struct omap_hwmod *oh, void *data) 2469static int __init _init(struct omap_hwmod *oh, void *data)
2424{ 2470{
2425 int r; 2471 int r, index;
2426 struct device_node *np = NULL; 2472 struct device_node *np = NULL;
2427 2473
2428 if (oh->_state != _HWMOD_STATE_REGISTERED) 2474 if (oh->_state != _HWMOD_STATE_REGISTERED)
2429 return 0; 2475 return 0;
2430 2476
2431 if (of_have_populated_dt()) 2477 if (of_have_populated_dt()) {
2432 np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); 2478 struct device_node *bus;
2479
2480 bus = of_find_node_by_name(NULL, "ocp");
2481 if (!bus)
2482 return -ENODEV;
2483
2484 r = of_dev_hwmod_lookup(bus, oh, &index, &np);
2485 if (r)
2486 pr_debug("omap_hwmod: %s missing dt data\n", oh->name);
2487 else if (np && index)
2488 pr_warn("omap_hwmod: %s using broken dt data from %s\n",
2489 oh->name, np->name);
2490 }
2433 2491
2434 if (oh->class->sysc) { 2492 if (oh->class->sysc) {
2435 r = _init_mpu_rt_base(oh, NULL, np); 2493 r = _init_mpu_rt_base(oh, NULL, index, np);
2436 if (r < 0) { 2494 if (r < 0) {
2437 WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n", 2495 WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
2438 oh->name); 2496 oh->name);