diff options
-rw-r--r-- | drivers/gpio/langwell_gpio.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index f658af016f44..560ab648cf18 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c | |||
@@ -190,23 +190,22 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) | |||
190 | struct irq_data *data = irq_desc_get_irq_data(desc); | 190 | struct irq_data *data = irq_desc_get_irq_data(desc); |
191 | struct lnw_gpio *lnw = irq_data_get_irq_handler_data(data); | 191 | struct lnw_gpio *lnw = irq_data_get_irq_handler_data(data); |
192 | struct irq_chip *chip = irq_data_get_irq_chip(data); | 192 | struct irq_chip *chip = irq_data_get_irq_chip(data); |
193 | u32 base, gpio, gedr_v; | 193 | u32 base, gpio, mask; |
194 | unsigned long pending; | 194 | unsigned long pending; |
195 | void __iomem *gedr; | 195 | void __iomem *gedr; |
196 | 196 | ||
197 | /* check GPIO controller to check which pin triggered the interrupt */ | 197 | /* check GPIO controller to check which pin triggered the interrupt */ |
198 | for (base = 0; base < lnw->chip.ngpio; base += 32) { | 198 | for (base = 0; base < lnw->chip.ngpio; base += 32) { |
199 | gedr = gpio_reg(&lnw->chip, base, GEDR); | 199 | gedr = gpio_reg(&lnw->chip, base, GEDR); |
200 | gedr_v = pending = readl(gedr); | 200 | pending = readl(gedr); |
201 | if (!gedr_v) | ||
202 | continue; | ||
203 | while (pending) { | 201 | while (pending) { |
204 | gpio = __ffs(pending) - 1; | 202 | gpio = __ffs(pending) - 1; |
205 | pending &= ~BIT(gpio); | 203 | mask = BIT(gpio); |
204 | pending &= ~mask; | ||
205 | /* Clear before handling so we can't lose an edge */ | ||
206 | writel(mask, gedr); | ||
206 | generic_handle_irq(lnw->irq_base + base + gpio); | 207 | generic_handle_irq(lnw->irq_base + base + gpio); |
207 | } | 208 | } |
208 | /* clear the edge detect status bit */ | ||
209 | writel(gedr_v, gedr); | ||
210 | } | 209 | } |
211 | 210 | ||
212 | chip->irq_eoi(data); | 211 | chip->irq_eoi(data); |