aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTero Kristo <tero.kristo@nokia.com>2008-12-22 07:27:12 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-05-12 12:39:16 -0400
commita118b5f3391fc60e1619a79f8ceb070bb7b39b2d (patch)
treed8c7b3aadf2e6b92cabd3651f181b2196a76669e
parentb57f95a38233a2e73b679bea4a5453a1cc2a1cc9 (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.c10
-rw-r--r--arch/arm/plat-omap/gpio.c19
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;
2031void omap2_gpio_prepare_for_retention(void) 2034void 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)
2088void omap2_gpio_resume_after_retention(void) 2094void 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