aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorKevin Hilman <khilman@mvista.com>2008-01-17 00:56:15 -0500
committerTony Lindgren <tony@atomide.com>2008-04-14 12:57:10 -0400
commitb144ff6f3068602e5bbcefab888b97bcedb9b4a5 (patch)
tree2f9c4aee5178ac496be9a8f825584c4549cbc2ae /arch/arm/plat-omap
parentd94577d5a581fe55c46b5b82eee733b8d053db19 (diff)
ARM: OMAP: Clear level-triggered GPIO interrupts in unmask hook
The clearing was moved to the unmask hook because it is known to run after the interrupt handler has actually run. Before this patch, if interrupts are threaded, the clearing/unmasking of level triggered interrupts would be done before the threaded handler actually ran. Signed-off-by: Kevin Hilman <khilman@mvista.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/gpio.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 56889fdb0740..4f104e4f6c04 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -148,6 +148,7 @@ struct gpio_bank {
148 u32 saved_fallingdetect; 148 u32 saved_fallingdetect;
149 u32 saved_risingdetect; 149 u32 saved_risingdetect;
150#endif 150#endif
151 u32 level_mask;
151 spinlock_t lock; 152 spinlock_t lock;
152 struct gpio_chip chip; 153 struct gpio_chip chip;
153}; 154};
@@ -538,6 +539,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
538 bank->enabled_non_wakeup_gpios &= ~gpio_bit; 539 bank->enabled_non_wakeup_gpios &= ~gpio_bit;
539 } 540 }
540 541
542 bank->level_mask =
543 __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
544 __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
541 /* 545 /*
542 * FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only 546 * FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only
543 * level triggering requested. 547 * level triggering requested.
@@ -1021,12 +1025,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
1021 isr &= 0x0000ffff; 1025 isr &= 0x0000ffff;
1022 1026
1023 if (cpu_class_is_omap2()) { 1027 if (cpu_class_is_omap2()) {
1024 level_mask = 1028 level_mask = bank->level_mask & enabled;
1025 __raw_readl(bank->base +
1026 OMAP24XX_GPIO_LEVELDETECT0) |
1027 __raw_readl(bank->base +
1028 OMAP24XX_GPIO_LEVELDETECT1);
1029 level_mask &= enabled;
1030 } 1029 }
1031 1030
1032 /* clear edge sensitive interrupts before handler(s) are 1031 /* clear edge sensitive interrupts before handler(s) are
@@ -1088,14 +1087,6 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
1088 retrigger |= irq_mask; 1087 retrigger |= irq_mask;
1089 } 1088 }
1090 } 1089 }
1091
1092 if (cpu_class_is_omap2()) {
1093 /* clear level sensitive interrupts after handler(s) */
1094 _enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
1095 _clear_gpio_irqbank(bank, isr_saved & level_mask);
1096 _enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
1097 }
1098
1099 } 1090 }
1100 /* if bank has any level sensitive GPIO pin interrupt 1091 /* if bank has any level sensitive GPIO pin interrupt
1101 configured, we must unmask the bank interrupt only after 1092 configured, we must unmask the bank interrupt only after
@@ -1134,6 +1125,14 @@ static void gpio_unmask_irq(unsigned int irq)
1134{ 1125{
1135 unsigned int gpio = irq - IH_GPIO_BASE; 1126 unsigned int gpio = irq - IH_GPIO_BASE;
1136 struct gpio_bank *bank = get_irq_chip_data(irq); 1127 struct gpio_bank *bank = get_irq_chip_data(irq);
1128 unsigned int irq_mask = 1 << get_gpio_index(gpio);
1129
1130 /* For level-triggered GPIOs, the clearing must be done after
1131 * the HW source is cleared, thus after the handler has run */
1132 if (bank->level_mask & irq_mask) {
1133 _set_gpio_irqenable(bank, gpio, 0);
1134 _clear_gpio_irqstatus(bank, gpio);
1135 }
1137 1136
1138 _set_gpio_irqenable(bank, gpio, 1); 1137 _set_gpio_irqenable(bank, gpio, 1);
1139} 1138}