diff options
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 27 |
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 | } |