OSDN Git Service

gpio: lynxpoint: Use for_each_set_bit() in IRQ handler
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 6 Nov 2018 12:38:55 +0000 (14:38 +0200)
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Mon, 3 Dec 2018 11:29:56 +0000 (13:29 +0200)
This simplifies and standardizes the AB IRQ handler by using
the for_each_set_bit() library function.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
drivers/gpio/gpio-lynxpoint.c

index b5b5e50..46560d5 100644 (file)
@@ -240,21 +240,23 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
        struct gpio_chip *gc = irq_desc_get_handler_data(desc);
        struct lp_gpio *lg = gpiochip_get_data(gc);
        struct irq_chip *chip = irq_data_get_irq_chip(data);
-       u32 base, pin, mask;
        unsigned long reg, ena, pending;
+       u32 base, pin;
 
        /* check from GPIO controller which pin triggered the interrupt */
        for (base = 0; base < lg->chip.ngpio; base += 32) {
                reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT);
                ena = lp_gpio_reg(&lg->chip, base, LP_INT_ENABLE);
 
-               while ((pending = (inl(reg) & inl(ena)))) {
+               /* Only interrupts that are enabled */
+               pending = inl(reg) & inl(ena);
+
+               for_each_set_bit(pin, &pending, 32) {
                        unsigned irq;
 
-                       pin = __ffs(pending);
-                       mask = BIT(pin);
                        /* Clear before handling so we don't lose an edge */
-                       outl(mask, reg);
+                       outl(BIT(pin), reg);
+
                        irq = irq_find_mapping(lg->chip.irq.domain, base + pin);
                        generic_handle_irq(irq);
                }