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.c85
1 files changed, 44 insertions, 41 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index eba6cd3816f5..7144ae651d3d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1395,7 +1395,7 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
1395 */ 1395 */
1396static int _ocp_softreset(struct omap_hwmod *oh) 1396static int _ocp_softreset(struct omap_hwmod *oh)
1397{ 1397{
1398 u32 v; 1398 u32 v, softrst_mask;
1399 int c = 0; 1399 int c = 0;
1400 int ret = 0; 1400 int ret = 0;
1401 1401
@@ -1422,16 +1422,21 @@ static int _ocp_softreset(struct omap_hwmod *oh)
1422 goto dis_opt_clks; 1422 goto dis_opt_clks;
1423 _write_sysconfig(v, oh); 1423 _write_sysconfig(v, oh);
1424 1424
1425 if (oh->class->sysc->srst_udelay)
1426 udelay(oh->class->sysc->srst_udelay);
1427
1425 if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) 1428 if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
1426 omap_test_timeout((omap_hwmod_read(oh, 1429 omap_test_timeout((omap_hwmod_read(oh,
1427 oh->class->sysc->syss_offs) 1430 oh->class->sysc->syss_offs)
1428 & SYSS_RESETDONE_MASK), 1431 & SYSS_RESETDONE_MASK),
1429 MAX_MODULE_SOFTRESET_WAIT, c); 1432 MAX_MODULE_SOFTRESET_WAIT, c);
1430 else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) 1433 else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
1434 softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
1431 omap_test_timeout(!(omap_hwmod_read(oh, 1435 omap_test_timeout(!(omap_hwmod_read(oh,
1432 oh->class->sysc->sysc_offs) 1436 oh->class->sysc->sysc_offs)
1433 & SYSC_TYPE2_SOFTRESET_MASK), 1437 & softrst_mask),
1434 MAX_MODULE_SOFTRESET_WAIT, c); 1438 MAX_MODULE_SOFTRESET_WAIT, c);
1439 }
1435 1440
1436 if (c == MAX_MODULE_SOFTRESET_WAIT) 1441 if (c == MAX_MODULE_SOFTRESET_WAIT)
1437 pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", 1442 pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
@@ -1477,6 +1482,11 @@ static int _reset(struct omap_hwmod *oh)
1477 1482
1478 ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh); 1483 ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh);
1479 1484
1485 if (oh->class->sysc) {
1486 _update_sysc_cache(oh);
1487 _enable_sysc(oh);
1488 }
1489
1480 return ret; 1490 return ret;
1481} 1491}
1482 1492
@@ -1786,20 +1796,9 @@ static int _setup(struct omap_hwmod *oh, void *data)
1786 return 0; 1796 return 0;
1787 } 1797 }
1788 1798
1789 if (!(oh->flags & HWMOD_INIT_NO_RESET)) { 1799 if (!(oh->flags & HWMOD_INIT_NO_RESET))
1790 _reset(oh); 1800 _reset(oh);
1791 1801
1792 /*
1793 * OCP_SYSCONFIG bits need to be reprogrammed after a softreset.
1794 * The _enable() function should be split to
1795 * avoid the rewrite of the OCP_SYSCONFIG register.
1796 */
1797 if (oh->class->sysc) {
1798 _update_sysc_cache(oh);
1799 _enable_sysc(oh);
1800 }
1801 }
1802
1803 postsetup_state = oh->_postsetup_state; 1802 postsetup_state = oh->_postsetup_state;
1804 if (postsetup_state == _HWMOD_STATE_UNKNOWN) 1803 if (postsetup_state == _HWMOD_STATE_UNKNOWN)
1805 postsetup_state = _HWMOD_STATE_ENABLED; 1804 postsetup_state = _HWMOD_STATE_ENABLED;
@@ -2463,26 +2462,28 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
2463 * @oh: struct omap_hwmod * 2462 * @oh: struct omap_hwmod *
2464 * 2463 *
2465 * Sets the module OCP socket ENAWAKEUP bit to allow the module to 2464 * Sets the module OCP socket ENAWAKEUP bit to allow the module to
2466 * send wakeups to the PRCM. Eventually this should sets PRCM wakeup 2465 * send wakeups to the PRCM, and enable I/O ring wakeup events for
2467 * registers to cause the PRCM to receive wakeup events from the 2466 * this IP block if it has dynamic mux entries. Eventually this
2468 * module. Does not set any wakeup routing registers beyond this 2467 * should set PRCM wakeup registers to cause the PRCM to receive
2469 * point - if the module is to wake up any other module or subsystem, 2468 * wakeup events from the module. Does not set any wakeup routing
2470 * that must be set separately. Called by omap_device code. Returns 2469 * registers beyond this point - if the module is to wake up any other
2471 * -EINVAL on error or 0 upon success. 2470 * module or subsystem, that must be set separately. Called by
2471 * omap_device code. Returns -EINVAL on error or 0 upon success.
2472 */ 2472 */
2473int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) 2473int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
2474{ 2474{
2475 unsigned long flags; 2475 unsigned long flags;
2476 u32 v; 2476 u32 v;
2477 2477
2478 if (!oh->class->sysc ||
2479 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
2480 return -EINVAL;
2481
2482 spin_lock_irqsave(&oh->_lock, flags); 2478 spin_lock_irqsave(&oh->_lock, flags);
2483 v = oh->_sysc_cache; 2479
2484 _enable_wakeup(oh, &v); 2480 if (oh->class->sysc &&
2485 _write_sysconfig(v, oh); 2481 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
2482 v = oh->_sysc_cache;
2483 _enable_wakeup(oh, &v);
2484 _write_sysconfig(v, oh);
2485 }
2486
2486 _set_idle_ioring_wakeup(oh, true); 2487 _set_idle_ioring_wakeup(oh, true);
2487 spin_unlock_irqrestore(&oh->_lock, flags); 2488 spin_unlock_irqrestore(&oh->_lock, flags);
2488 2489
@@ -2494,26 +2495,28 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
2494 * @oh: struct omap_hwmod * 2495 * @oh: struct omap_hwmod *
2495 * 2496 *
2496 * Clears the module OCP socket ENAWAKEUP bit to prevent the module 2497 * Clears the module OCP socket ENAWAKEUP bit to prevent the module
2497 * from sending wakeups to the PRCM. Eventually this should clear 2498 * from sending wakeups to the PRCM, and disable I/O ring wakeup
2498 * PRCM wakeup registers to cause the PRCM to ignore wakeup events 2499 * events for this IP block if it has dynamic mux entries. Eventually
2499 * from the module. Does not set any wakeup routing registers beyond 2500 * this should clear PRCM wakeup registers to cause the PRCM to ignore
2500 * this point - if the module is to wake up any other module or 2501 * wakeup events from the module. Does not set any wakeup routing
2501 * subsystem, that must be set separately. Called by omap_device 2502 * registers beyond this point - if the module is to wake up any other
2502 * code. Returns -EINVAL on error or 0 upon success. 2503 * module or subsystem, that must be set separately. Called by
2504 * omap_device code. Returns -EINVAL on error or 0 upon success.
2503 */ 2505 */
2504int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) 2506int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
2505{ 2507{
2506 unsigned long flags; 2508 unsigned long flags;
2507 u32 v; 2509 u32 v;
2508 2510
2509 if (!oh->class->sysc ||
2510 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
2511 return -EINVAL;
2512
2513 spin_lock_irqsave(&oh->_lock, flags); 2511 spin_lock_irqsave(&oh->_lock, flags);
2514 v = oh->_sysc_cache; 2512
2515 _disable_wakeup(oh, &v); 2513 if (oh->class->sysc &&
2516 _write_sysconfig(v, oh); 2514 (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
2515 v = oh->_sysc_cache;
2516 _disable_wakeup(oh, &v);
2517 _write_sysconfig(v, oh);
2518 }
2519
2517 _set_idle_ioring_wakeup(oh, false); 2520 _set_idle_ioring_wakeup(oh, false);
2518 spin_unlock_irqrestore(&oh->_lock, flags); 2521 spin_unlock_irqrestore(&oh->_lock, flags);
2519 2522