diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 85 |
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 | */ |
1396 | static int _ocp_softreset(struct omap_hwmod *oh) | 1396 | static 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 | */ |
2473 | int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) | 2473 | int 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 | */ |
2504 | int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) | 2506 | int 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 | ||