diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 96 |
1 files changed, 43 insertions, 53 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index eba6cd3816f5..2c27fdb61e66 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 | ||
@@ -1427,11 +1427,13 @@ static int _ocp_softreset(struct omap_hwmod *oh) | |||
1427 | oh->class->sysc->syss_offs) | 1427 | oh->class->sysc->syss_offs) |
1428 | & SYSS_RESETDONE_MASK), | 1428 | & SYSS_RESETDONE_MASK), |
1429 | MAX_MODULE_SOFTRESET_WAIT, c); | 1429 | MAX_MODULE_SOFTRESET_WAIT, c); |
1430 | else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) | 1430 | else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { |
1431 | softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); | ||
1431 | omap_test_timeout(!(omap_hwmod_read(oh, | 1432 | omap_test_timeout(!(omap_hwmod_read(oh, |
1432 | oh->class->sysc->sysc_offs) | 1433 | oh->class->sysc->sysc_offs) |
1433 | & SYSC_TYPE2_SOFTRESET_MASK), | 1434 | & softrst_mask), |
1434 | MAX_MODULE_SOFTRESET_WAIT, c); | 1435 | MAX_MODULE_SOFTRESET_WAIT, c); |
1436 | } | ||
1435 | 1437 | ||
1436 | if (c == MAX_MODULE_SOFTRESET_WAIT) | 1438 | if (c == MAX_MODULE_SOFTRESET_WAIT) |
1437 | pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", | 1439 | pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", |
@@ -1477,6 +1479,11 @@ static int _reset(struct omap_hwmod *oh) | |||
1477 | 1479 | ||
1478 | ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh); | 1480 | ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh); |
1479 | 1481 | ||
1482 | if (oh->class->sysc) { | ||
1483 | _update_sysc_cache(oh); | ||
1484 | _enable_sysc(oh); | ||
1485 | } | ||
1486 | |||
1480 | return ret; | 1487 | return ret; |
1481 | } | 1488 | } |
1482 | 1489 | ||
@@ -1786,20 +1793,9 @@ static int _setup(struct omap_hwmod *oh, void *data) | |||
1786 | return 0; | 1793 | return 0; |
1787 | } | 1794 | } |
1788 | 1795 | ||
1789 | if (!(oh->flags & HWMOD_INIT_NO_RESET)) { | 1796 | if (!(oh->flags & HWMOD_INIT_NO_RESET)) |
1790 | _reset(oh); | 1797 | _reset(oh); |
1791 | 1798 | ||
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; | 1799 | postsetup_state = oh->_postsetup_state; |
1804 | if (postsetup_state == _HWMOD_STATE_UNKNOWN) | 1800 | if (postsetup_state == _HWMOD_STATE_UNKNOWN) |
1805 | postsetup_state = _HWMOD_STATE_ENABLED; | 1801 | postsetup_state = _HWMOD_STATE_ENABLED; |
@@ -1907,20 +1903,10 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) | |||
1907 | */ | 1903 | */ |
1908 | int omap_hwmod_softreset(struct omap_hwmod *oh) | 1904 | int omap_hwmod_softreset(struct omap_hwmod *oh) |
1909 | { | 1905 | { |
1910 | u32 v; | 1906 | if (!oh) |
1911 | int ret; | ||
1912 | |||
1913 | if (!oh || !(oh->_sysc_cache)) | ||
1914 | return -EINVAL; | 1907 | return -EINVAL; |
1915 | 1908 | ||
1916 | v = oh->_sysc_cache; | 1909 | return _ocp_softreset(oh); |
1917 | ret = _set_softreset(oh, &v); | ||
1918 | if (ret) | ||
1919 | goto error; | ||
1920 | _write_sysconfig(v, oh); | ||
1921 | |||
1922 | error: | ||
1923 | return ret; | ||
1924 | } | 1910 | } |
1925 | 1911 | ||
1926 | /** | 1912 | /** |
@@ -2463,26 +2449,28 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh, | |||
2463 | * @oh: struct omap_hwmod * | 2449 | * @oh: struct omap_hwmod * |
2464 | * | 2450 | * |
2465 | * Sets the module OCP socket ENAWAKEUP bit to allow the module to | 2451 | * Sets the module OCP socket ENAWAKEUP bit to allow the module to |
2466 | * send wakeups to the PRCM. Eventually this should sets PRCM wakeup | 2452 | * 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 | 2453 | * this IP block if it has dynamic mux entries. Eventually this |
2468 | * module. Does not set any wakeup routing registers beyond this | 2454 | * 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, | 2455 | * wakeup events from the module. Does not set any wakeup routing |
2470 | * that must be set separately. Called by omap_device code. Returns | 2456 | * registers beyond this point - if the module is to wake up any other |
2471 | * -EINVAL on error or 0 upon success. | 2457 | * module or subsystem, that must be set separately. Called by |
2458 | * omap_device code. Returns -EINVAL on error or 0 upon success. | ||
2472 | */ | 2459 | */ |
2473 | int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) | 2460 | int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) |
2474 | { | 2461 | { |
2475 | unsigned long flags; | 2462 | unsigned long flags; |
2476 | u32 v; | 2463 | u32 v; |
2477 | 2464 | ||
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); | 2465 | spin_lock_irqsave(&oh->_lock, flags); |
2483 | v = oh->_sysc_cache; | 2466 | |
2484 | _enable_wakeup(oh, &v); | 2467 | if (oh->class->sysc && |
2485 | _write_sysconfig(v, oh); | 2468 | (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { |
2469 | v = oh->_sysc_cache; | ||
2470 | _enable_wakeup(oh, &v); | ||
2471 | _write_sysconfig(v, oh); | ||
2472 | } | ||
2473 | |||
2486 | _set_idle_ioring_wakeup(oh, true); | 2474 | _set_idle_ioring_wakeup(oh, true); |
2487 | spin_unlock_irqrestore(&oh->_lock, flags); | 2475 | spin_unlock_irqrestore(&oh->_lock, flags); |
2488 | 2476 | ||
@@ -2494,26 +2482,28 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) | |||
2494 | * @oh: struct omap_hwmod * | 2482 | * @oh: struct omap_hwmod * |
2495 | * | 2483 | * |
2496 | * Clears the module OCP socket ENAWAKEUP bit to prevent the module | 2484 | * Clears the module OCP socket ENAWAKEUP bit to prevent the module |
2497 | * from sending wakeups to the PRCM. Eventually this should clear | 2485 | * from sending wakeups to the PRCM, and disable I/O ring wakeup |
2498 | * PRCM wakeup registers to cause the PRCM to ignore wakeup events | 2486 | * events for this IP block if it has dynamic mux entries. Eventually |
2499 | * from the module. Does not set any wakeup routing registers beyond | 2487 | * 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 | 2488 | * wakeup events from the module. Does not set any wakeup routing |
2501 | * subsystem, that must be set separately. Called by omap_device | 2489 | * registers beyond this point - if the module is to wake up any other |
2502 | * code. Returns -EINVAL on error or 0 upon success. | 2490 | * module or subsystem, that must be set separately. Called by |
2491 | * omap_device code. Returns -EINVAL on error or 0 upon success. | ||
2503 | */ | 2492 | */ |
2504 | int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) | 2493 | int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) |
2505 | { | 2494 | { |
2506 | unsigned long flags; | 2495 | unsigned long flags; |
2507 | u32 v; | 2496 | u32 v; |
2508 | 2497 | ||
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); | 2498 | spin_lock_irqsave(&oh->_lock, flags); |
2514 | v = oh->_sysc_cache; | 2499 | |
2515 | _disable_wakeup(oh, &v); | 2500 | if (oh->class->sysc && |
2516 | _write_sysconfig(v, oh); | 2501 | (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { |
2502 | v = oh->_sysc_cache; | ||
2503 | _disable_wakeup(oh, &v); | ||
2504 | _write_sysconfig(v, oh); | ||
2505 | } | ||
2506 | |||
2517 | _set_idle_ioring_wakeup(oh, false); | 2507 | _set_idle_ioring_wakeup(oh, false); |
2518 | spin_unlock_irqrestore(&oh->_lock, flags); | 2508 | spin_unlock_irqrestore(&oh->_lock, flags); |
2519 | 2509 | ||