diff options
author | Tony Lindgren <tony@atomide.com> | 2012-11-06 12:55:20 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2012-11-06 12:55:20 -0500 |
commit | 5dfcb3b58c6c8934dec8898827736a1e26732cdd (patch) | |
tree | 1b1f40e80be8e12e3b2ef523e2bbe1481a7e898a /arch | |
parent | 55f4851a0b141faac119f04212e2911fd968812a (diff) | |
parent | bc05244e65f26b7b6f87e0964bfe277803914ed9 (diff) |
Merge tag 'omap-fixes-b2-for-3.7-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.7-rc4/fixes
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/clockdomains44xx_data.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 63 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 8 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 |
4 files changed, 64 insertions, 15 deletions
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index b56d06b48782..95192a062d5d 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c | |||
@@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { | |||
359 | .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, | 359 | .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, |
360 | .wkdep_srcs = iss_wkup_sleep_deps, | 360 | .wkdep_srcs = iss_wkup_sleep_deps, |
361 | .sleepdep_srcs = iss_wkup_sleep_deps, | 361 | .sleepdep_srcs = iss_wkup_sleep_deps, |
362 | .flags = CLKDM_CAN_HWSUP_SWSUP, | 362 | .flags = CLKDM_CAN_SWSUP, |
363 | }; | 363 | }; |
364 | 364 | ||
365 | static struct clockdomain l3_dss_44xx_clkdm = { | 365 | static struct clockdomain l3_dss_44xx_clkdm = { |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b969ab1d258b..87cc6d058de2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -422,6 +422,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) | |||
422 | } | 422 | } |
423 | 423 | ||
424 | /** | 424 | /** |
425 | * _wait_softreset_complete - wait for an OCP softreset to complete | ||
426 | * @oh: struct omap_hwmod * to wait on | ||
427 | * | ||
428 | * Wait until the IP block represented by @oh reports that its OCP | ||
429 | * softreset is complete. This can be triggered by software (see | ||
430 | * _ocp_softreset()) or by hardware upon returning from off-mode (one | ||
431 | * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT | ||
432 | * microseconds. Returns the number of microseconds waited. | ||
433 | */ | ||
434 | static int _wait_softreset_complete(struct omap_hwmod *oh) | ||
435 | { | ||
436 | struct omap_hwmod_class_sysconfig *sysc; | ||
437 | u32 softrst_mask; | ||
438 | int c = 0; | ||
439 | |||
440 | sysc = oh->class->sysc; | ||
441 | |||
442 | if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) | ||
443 | omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) | ||
444 | & SYSS_RESETDONE_MASK), | ||
445 | MAX_MODULE_SOFTRESET_WAIT, c); | ||
446 | else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { | ||
447 | softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); | ||
448 | omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) | ||
449 | & softrst_mask), | ||
450 | MAX_MODULE_SOFTRESET_WAIT, c); | ||
451 | } | ||
452 | |||
453 | return c; | ||
454 | } | ||
455 | |||
456 | /** | ||
425 | * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v | 457 | * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v |
426 | * @oh: struct omap_hwmod * | 458 | * @oh: struct omap_hwmod * |
427 | * | 459 | * |
@@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) | |||
1282 | if (!oh->class->sysc) | 1314 | if (!oh->class->sysc) |
1283 | return; | 1315 | return; |
1284 | 1316 | ||
1317 | /* | ||
1318 | * Wait until reset has completed, this is needed as the IP | ||
1319 | * block is reset automatically by hardware in some cases | ||
1320 | * (off-mode for example), and the drivers require the | ||
1321 | * IP to be ready when they access it | ||
1322 | */ | ||
1323 | if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) | ||
1324 | _enable_optional_clocks(oh); | ||
1325 | _wait_softreset_complete(oh); | ||
1326 | if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) | ||
1327 | _disable_optional_clocks(oh); | ||
1328 | |||
1285 | v = oh->_sysc_cache; | 1329 | v = oh->_sysc_cache; |
1286 | sf = oh->class->sysc->sysc_flags; | 1330 | sf = oh->class->sysc->sysc_flags; |
1287 | 1331 | ||
@@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) | |||
1804 | */ | 1848 | */ |
1805 | static int _ocp_softreset(struct omap_hwmod *oh) | 1849 | static int _ocp_softreset(struct omap_hwmod *oh) |
1806 | { | 1850 | { |
1807 | u32 v, softrst_mask; | 1851 | u32 v; |
1808 | int c = 0; | 1852 | int c = 0; |
1809 | int ret = 0; | 1853 | int ret = 0; |
1810 | 1854 | ||
@@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) | |||
1834 | if (oh->class->sysc->srst_udelay) | 1878 | if (oh->class->sysc->srst_udelay) |
1835 | udelay(oh->class->sysc->srst_udelay); | 1879 | udelay(oh->class->sysc->srst_udelay); |
1836 | 1880 | ||
1837 | if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) | 1881 | c = _wait_softreset_complete(oh); |
1838 | omap_test_timeout((omap_hwmod_read(oh, | ||
1839 | oh->class->sysc->syss_offs) | ||
1840 | & SYSS_RESETDONE_MASK), | ||
1841 | MAX_MODULE_SOFTRESET_WAIT, c); | ||
1842 | else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { | ||
1843 | softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); | ||
1844 | omap_test_timeout(!(omap_hwmod_read(oh, | ||
1845 | oh->class->sysc->sysc_offs) | ||
1846 | & softrst_mask), | ||
1847 | MAX_MODULE_SOFTRESET_WAIT, c); | ||
1848 | } | ||
1849 | |||
1850 | if (c == MAX_MODULE_SOFTRESET_WAIT) | 1882 | if (c == MAX_MODULE_SOFTRESET_WAIT) |
1851 | pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", | 1883 | pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", |
1852 | oh->name, MAX_MODULE_SOFTRESET_WAIT); | 1884 | oh->name, MAX_MODULE_SOFTRESET_WAIT); |
@@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) | |||
2352 | if (oh->_state != _HWMOD_STATE_INITIALIZED) | 2384 | if (oh->_state != _HWMOD_STATE_INITIALIZED) |
2353 | return -EINVAL; | 2385 | return -EINVAL; |
2354 | 2386 | ||
2387 | if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) | ||
2388 | return -EPERM; | ||
2389 | |||
2355 | if (oh->rst_lines_cnt == 0) { | 2390 | if (oh->rst_lines_cnt == 0) { |
2356 | r = _enable(oh); | 2391 | r = _enable(oh); |
2357 | if (r) { | 2392 | if (r) { |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d0285bd6d..7bddfa5534f9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c | |||
@@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { | |||
2125 | .name = "mcpdm", | 2125 | .name = "mcpdm", |
2126 | .class = &omap44xx_mcpdm_hwmod_class, | 2126 | .class = &omap44xx_mcpdm_hwmod_class, |
2127 | .clkdm_name = "abe_clkdm", | 2127 | .clkdm_name = "abe_clkdm", |
2128 | /* | ||
2129 | * It's suspected that the McPDM requires an off-chip main | ||
2130 | * functional clock, controlled via I2C. This IP block is | ||
2131 | * currently reset very early during boot, before I2C is | ||
2132 | * available, so it doesn't seem that we have any choice in | ||
2133 | * the kernel other than to avoid resetting it. | ||
2134 | */ | ||
2135 | .flags = HWMOD_EXT_OPT_MAIN_CLK, | ||
2128 | .mpu_irqs = omap44xx_mcpdm_irqs, | 2136 | .mpu_irqs = omap44xx_mcpdm_irqs, |
2129 | .sdma_reqs = omap44xx_mcpdm_sdma_reqs, | 2137 | .sdma_reqs = omap44xx_mcpdm_sdma_reqs, |
2130 | .main_clk = "mcpdm_fck", | 2138 | .main_clk = "mcpdm_fck", |
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index b3349f7b1a2c..1db029438022 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h | |||
@@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm { | |||
443 | * in order to complete the reset. Optional clocks will be disabled | 443 | * in order to complete the reset. Optional clocks will be disabled |
444 | * again after the reset. | 444 | * again after the reset. |
445 | * HWMOD_16BIT_REG: Module has 16bit registers | 445 | * HWMOD_16BIT_REG: Module has 16bit registers |
446 | * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for | ||
447 | * this IP block comes from an off-chip source and is not always | ||
448 | * enabled. This prevents the hwmod code from being able to | ||
449 | * enable and reset the IP block early. XXX Eventually it should | ||
450 | * be possible to query the clock framework for this information. | ||
446 | */ | 451 | */ |
447 | #define HWMOD_SWSUP_SIDLE (1 << 0) | 452 | #define HWMOD_SWSUP_SIDLE (1 << 0) |
448 | #define HWMOD_SWSUP_MSTANDBY (1 << 1) | 453 | #define HWMOD_SWSUP_MSTANDBY (1 << 1) |
@@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm { | |||
453 | #define HWMOD_NO_IDLEST (1 << 6) | 458 | #define HWMOD_NO_IDLEST (1 << 6) |
454 | #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) | 459 | #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) |
455 | #define HWMOD_16BIT_REG (1 << 8) | 460 | #define HWMOD_16BIT_REG (1 << 8) |
461 | #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) | ||
456 | 462 | ||
457 | /* | 463 | /* |
458 | * omap_hwmod._int_flags definitions | 464 | * omap_hwmod._int_flags definitions |