diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-03-17 15:32:55 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-03-17 15:49:03 -0400 |
commit | 732063b92bb727b27e61580ce278dddefe31c6ad (patch) | |
tree | 3e524f09833a7a65f0f9ce3279c77b0c599d198d /drivers/gpio/langwell_gpio.c | |
parent | 674db90690a5988bdaa3bb2a54619c0de50d31e9 (diff) |
gpio/langwell: Simplify demux loop
Use __ffs() to find the pending interrupt source instead of looping 32
times.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Feng Tang <feng.tang@intel.com>
Cc: Alek Du <alek.du@intel.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio/langwell_gpio.c')
-rw-r--r-- | drivers/gpio/langwell_gpio.c | 13 |
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 | } |