aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/langwell_gpio.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 6efc4e60aca7..f658af016f44 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -191,19 +191,20 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *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, gedr_v;
194 unsigned long pending;
194 void __iomem *gedr; 195 void __iomem *gedr;
195 196
196 /* check GPIO controller to check which pin triggered the interrupt */ 197 /* check GPIO controller to check which pin triggered the interrupt */
197 for (base = 0; base < lnw->chip.ngpio; base += 32) { 198 for (base = 0; base < lnw->chip.ngpio; base += 32) {
198 gedr = gpio_reg(&lnw->chip, base, GEDR); 199 gedr = gpio_reg(&lnw->chip, base, GEDR);
199 gedr_v = readl(gedr); 200 gedr_v = pending = readl(gedr);
200 if (!gedr_v) 201 if (!gedr_v)
201 continue; 202 continue;
202 for (gpio = base; gpio < base + 32; gpio++) 203 while (pending) {
203 if (gedr_v & BIT(gpio % 32)) { 204 gpio = __ffs(pending) - 1;
204 pr_debug("pin %d triggered\n", gpio); 205 pending &= ~BIT(gpio);
205 generic_handle_irq(lnw->irq_base + gpio); 206 generic_handle_irq(lnw->irq_base + base + gpio);
206 } 207 }
207 /* clear the edge detect status bit */ 208 /* clear the edge detect status bit */
208 writel(gedr_v, gedr); 209 writel(gedr_v, gedr);
209 } 210 }