diff options
author | Tero Kristo <tero.kristo@nokia.com> | 2008-12-22 07:27:12 -0500 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-05-12 12:39:16 -0400 |
commit | a118b5f3391fc60e1619a79f8ceb070bb7b39b2d (patch) | |
tree | d8c7b3aadf2e6b92cabd3651f181b2196a76669e | |
parent | b57f95a38233a2e73b679bea4a5453a1cc2a1cc9 (diff) |
OMAP3: GPIO fixes for off-mode
Off mode is now using the omap2 retention fix code for scanning GPIOs
during off-mode transitions. All the *non_wakeup_gpios variables
are now used for off-mode transition tracking on OMAP3. This patch fixes
cases where GPIO state changes are missed during off-mode.
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 10 | ||||
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 19 |
2 files changed, 20 insertions, 9 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index ea0000bc5358..5de07db636bd 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -376,14 +376,15 @@ void omap_sram_idle(void) | |||
376 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); | 376 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); |
377 | if (per_next_state < PWRDM_POWER_ON) { | 377 | if (per_next_state < PWRDM_POWER_ON) { |
378 | omap_uart_prepare_idle(2); | 378 | omap_uart_prepare_idle(2); |
379 | omap2_gpio_prepare_for_retention(); | ||
380 | if (per_next_state == PWRDM_POWER_OFF) { | 379 | if (per_next_state == PWRDM_POWER_OFF) { |
381 | if (core_next_state == PWRDM_POWER_ON) { | 380 | if (core_next_state == PWRDM_POWER_ON) { |
382 | per_next_state = PWRDM_POWER_RET; | 381 | per_next_state = PWRDM_POWER_RET; |
383 | pwrdm_set_next_pwrst(per_pwrdm, per_next_state); | 382 | pwrdm_set_next_pwrst(per_pwrdm, per_next_state); |
384 | per_state_modified = 1; | 383 | per_state_modified = 1; |
385 | } else | 384 | } else { |
385 | omap2_gpio_prepare_for_retention(); | ||
386 | omap3_per_save_context(); | 386 | omap3_per_save_context(); |
387 | } | ||
387 | } | 388 | } |
388 | } | 389 | } |
389 | 390 | ||
@@ -454,9 +455,10 @@ void omap_sram_idle(void) | |||
454 | /* PER */ | 455 | /* PER */ |
455 | if (per_next_state < PWRDM_POWER_ON) { | 456 | if (per_next_state < PWRDM_POWER_ON) { |
456 | per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); | 457 | per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); |
457 | if (per_prev_state == PWRDM_POWER_OFF) | 458 | if (per_prev_state == PWRDM_POWER_OFF) { |
458 | omap3_per_restore_context(); | 459 | omap3_per_restore_context(); |
459 | omap2_gpio_resume_after_retention(); | 460 | omap2_gpio_resume_after_retention(); |
461 | } | ||
460 | omap_uart_resume_idle(2); | 462 | omap_uart_resume_idle(2); |
461 | if (per_state_modified) | 463 | if (per_state_modified) |
462 | pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); | 464 | pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF); |
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 45a225d09125..6216f4f09e82 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -731,7 +731,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
731 | __raw_writel(1 << gpio, bank->base | 731 | __raw_writel(1 << gpio, bank->base |
732 | + OMAP24XX_GPIO_CLEARWKUENA); | 732 | + OMAP24XX_GPIO_CLEARWKUENA); |
733 | } | 733 | } |
734 | } else { | 734 | } |
735 | /* This part needs to be executed always for OMAP34xx */ | ||
736 | if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { | ||
735 | if (trigger != 0) | 737 | if (trigger != 0) |
736 | bank->enabled_non_wakeup_gpios |= gpio_bit; | 738 | bank->enabled_non_wakeup_gpios |= gpio_bit; |
737 | else | 739 | else |
@@ -1845,7 +1847,8 @@ static int __init _omap_gpio_init(void) | |||
1845 | __raw_writel(0, bank->base + | 1847 | __raw_writel(0, bank->base + |
1846 | OMAP24XX_GPIO_CTRL); | 1848 | OMAP24XX_GPIO_CTRL); |
1847 | } | 1849 | } |
1848 | if (i < ARRAY_SIZE(non_wakeup_gpios)) | 1850 | if (cpu_is_omap24xx() && |
1851 | i < ARRAY_SIZE(non_wakeup_gpios)) | ||
1849 | bank->non_wakeup_gpios = non_wakeup_gpios[i]; | 1852 | bank->non_wakeup_gpios = non_wakeup_gpios[i]; |
1850 | gpio_count = 32; | 1853 | gpio_count = 32; |
1851 | } | 1854 | } |
@@ -2031,10 +2034,13 @@ static int workaround_enabled; | |||
2031 | void omap2_gpio_prepare_for_retention(void) | 2034 | void omap2_gpio_prepare_for_retention(void) |
2032 | { | 2035 | { |
2033 | int i, c = 0; | 2036 | int i, c = 0; |
2037 | int min = 0; | ||
2034 | 2038 | ||
2039 | if (cpu_is_omap34xx()) | ||
2040 | min = 1; | ||
2035 | /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious | 2041 | /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious |
2036 | * IRQs will be generated. See OMAP2420 Errata item 1.101. */ | 2042 | * IRQs will be generated. See OMAP2420 Errata item 1.101. */ |
2037 | for (i = 0; i < gpio_bank_count; i++) { | 2043 | for (i = min; i < gpio_bank_count; i++) { |
2038 | struct gpio_bank *bank = &gpio_bank[i]; | 2044 | struct gpio_bank *bank = &gpio_bank[i]; |
2039 | u32 l1, l2; | 2045 | u32 l1, l2; |
2040 | 2046 | ||
@@ -2088,10 +2094,13 @@ void omap2_gpio_prepare_for_retention(void) | |||
2088 | void omap2_gpio_resume_after_retention(void) | 2094 | void omap2_gpio_resume_after_retention(void) |
2089 | { | 2095 | { |
2090 | int i; | 2096 | int i; |
2097 | int min = 0; | ||
2091 | 2098 | ||
2092 | if (!workaround_enabled) | 2099 | if (!workaround_enabled) |
2093 | return; | 2100 | return; |
2094 | for (i = 0; i < gpio_bank_count; i++) { | 2101 | if (cpu_is_omap34xx()) |
2102 | min = 1; | ||
2103 | for (i = min; i < gpio_bank_count; i++) { | ||
2095 | struct gpio_bank *bank = &gpio_bank[i]; | 2104 | struct gpio_bank *bank = &gpio_bank[i]; |
2096 | u32 l, gen, gen0, gen1; | 2105 | u32 l, gen, gen0, gen1; |
2097 | 2106 | ||
@@ -2119,7 +2128,7 @@ void omap2_gpio_resume_after_retention(void) | |||
2119 | * horribly racy, but it's the best we can do to work around | 2128 | * horribly racy, but it's the best we can do to work around |
2120 | * this silicon bug. */ | 2129 | * this silicon bug. */ |
2121 | l ^= bank->saved_datain; | 2130 | l ^= bank->saved_datain; |
2122 | l &= bank->non_wakeup_gpios; | 2131 | l &= bank->enabled_non_wakeup_gpios; |
2123 | 2132 | ||
2124 | /* | 2133 | /* |
2125 | * No need to generate IRQs for the rising edge for gpio IRQs | 2134 | * No need to generate IRQs for the rising edge for gpio IRQs |