aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap_hwmod.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-11-26 00:34:34 -0500
committerOlof Johansson <olof@lixom.net>2012-11-26 00:34:34 -0500
commit0f9cb211ba5db93d488fe6b154138231fdd0e22d (patch)
tree293871b042e9ebc49b1d783f1b110eef541ddc97 /arch/arm/mach-omap2/omap_hwmod.c
parent007108a2279123ad6639b6c653ad1a731febb60f (diff)
parent9489e9dcae718d5fde988e4a684a0f55b5f94d17 (diff)
Merge tag 'v3.7-rc7' into next/cleanup
Merging in mainline back to next/cleanup since it has collected a few conflicts between fixes going upstream and some of the cleanup patches. Git doesn't auto-resolve some of them, and they're mostly noise so let's take care of it locally. Conflicts are in: arch/arm/mach-omap2/omap_hwmod_44xx_data.c arch/arm/plat-omap/i2c.c drivers/video/omap2/dss/dss.c Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 139adca3bda1..b3b00f43dd7c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -420,6 +420,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
420} 420}
421 421
422/** 422/**
423 * _wait_softreset_complete - wait for an OCP softreset to complete
424 * @oh: struct omap_hwmod * to wait on
425 *
426 * Wait until the IP block represented by @oh reports that its OCP
427 * softreset is complete. This can be triggered by software (see
428 * _ocp_softreset()) or by hardware upon returning from off-mode (one
429 * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT
430 * microseconds. Returns the number of microseconds waited.
431 */
432static int _wait_softreset_complete(struct omap_hwmod *oh)
433{
434 struct omap_hwmod_class_sysconfig *sysc;
435 u32 softrst_mask;
436 int c = 0;
437
438 sysc = oh->class->sysc;
439
440 if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
441 omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
442 & SYSS_RESETDONE_MASK),
443 MAX_MODULE_SOFTRESET_WAIT, c);
444 else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
445 softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
446 omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
447 & softrst_mask),
448 MAX_MODULE_SOFTRESET_WAIT, c);
449 }
450
451 return c;
452}
453
454/**
423 * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v 455 * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
424 * @oh: struct omap_hwmod * 456 * @oh: struct omap_hwmod *
425 * 457 *
@@ -1280,6 +1312,18 @@ static void _enable_sysc(struct omap_hwmod *oh)
1280 if (!oh->class->sysc) 1312 if (!oh->class->sysc)
1281 return; 1313 return;
1282 1314
1315 /*
1316 * Wait until reset has completed, this is needed as the IP
1317 * block is reset automatically by hardware in some cases
1318 * (off-mode for example), and the drivers require the
1319 * IP to be ready when they access it
1320 */
1321 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1322 _enable_optional_clocks(oh);
1323 _wait_softreset_complete(oh);
1324 if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
1325 _disable_optional_clocks(oh);
1326
1283 v = oh->_sysc_cache; 1327 v = oh->_sysc_cache;
1284 sf = oh->class->sysc->sysc_flags; 1328 sf = oh->class->sysc->sysc_flags;
1285 1329
@@ -1802,7 +1846,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
1802 */ 1846 */
1803static int _ocp_softreset(struct omap_hwmod *oh) 1847static int _ocp_softreset(struct omap_hwmod *oh)
1804{ 1848{
1805 u32 v, softrst_mask; 1849 u32 v;
1806 int c = 0; 1850 int c = 0;
1807 int ret = 0; 1851 int ret = 0;
1808 1852
@@ -1832,19 +1876,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)
1832 if (oh->class->sysc->srst_udelay) 1876 if (oh->class->sysc->srst_udelay)
1833 udelay(oh->class->sysc->srst_udelay); 1877 udelay(oh->class->sysc->srst_udelay);
1834 1878
1835 if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) 1879 c = _wait_softreset_complete(oh);
1836 omap_test_timeout((omap_hwmod_read(oh,
1837 oh->class->sysc->syss_offs)
1838 & SYSS_RESETDONE_MASK),
1839 MAX_MODULE_SOFTRESET_WAIT, c);
1840 else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
1841 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
1842 omap_test_timeout(!(omap_hwmod_read(oh,
1843 oh->class->sysc->sysc_offs)
1844 & softrst_mask),
1845 MAX_MODULE_SOFTRESET_WAIT, c);
1846 }
1847
1848 if (c == MAX_MODULE_SOFTRESET_WAIT) 1880 if (c == MAX_MODULE_SOFTRESET_WAIT)
1849 pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", 1881 pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
1850 oh->name, MAX_MODULE_SOFTRESET_WAIT); 1882 oh->name, MAX_MODULE_SOFTRESET_WAIT);
@@ -2351,6 +2383,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)
2351 if (oh->_state != _HWMOD_STATE_INITIALIZED) 2383 if (oh->_state != _HWMOD_STATE_INITIALIZED)
2352 return -EINVAL; 2384 return -EINVAL;
2353 2385
2386 if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
2387 return -EPERM;
2388
2354 if (oh->rst_lines_cnt == 0) { 2389 if (oh->rst_lines_cnt == 0) {
2355 r = _enable(oh); 2390 r = _enable(oh);
2356 if (r) { 2391 if (r) {