diff options
Diffstat (limited to 'drivers/gpio')
-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 f658af016f4..560ab648cf1 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) struct irq_data *data = irq_desc_get_irq_data(desc); struct lnw_gpio *lnw = irq_data_get_irq_handler_data(data); struct irq_chip *chip = irq_data_get_irq_chip(data); - u32 base, gpio, gedr_v; + u32 base, gpio, mask; unsigned long pending; void __iomem *gedr; /* check GPIO controller to check which pin triggered the interrupt */ for (base = 0; base < lnw->chip.ngpio; base += 32) { gedr = gpio_reg(&lnw->chip, base, GEDR); - gedr_v = pending = readl(gedr); - if (!gedr_v) - continue; + pending = readl(gedr); while (pending) { gpio = __ffs(pending) - 1; - pending &= ~BIT(gpio); + mask = BIT(gpio); + pending &= ~mask; + /* Clear before handling so we can't lose an edge */ + writel(mask, gedr); generic_handle_irq(lnw->irq_base + base + gpio); } - /* clear the edge detect status bit */ - writel(gedr_v, gedr); } chip->irq_eoi(data); |