summaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-03-17 19:32:55 +0000
committerGrant Likely <grant.likely@secretlab.ca>2011-03-17 13:49:03 -0600
commit732063b92bb727b27e61580ce278dddefe31c6ad (patch)
tree3e524f09833a7a65f0f9ce3279c77b0c599d198d /drivers/gpio
parent674db90690a5988bdaa3bb2a54619c0de50d31e9 (diff)
downloadop-kernel-dev-732063b92bb727b27e61580ce278dddefe31c6ad.zip
op-kernel-dev-732063b92bb727b27e61580ce278dddefe31c6ad.tar.gz
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')
-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 6efc4e6..f658af0 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)
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;
+ 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 = readl(gedr);
+ gedr_v = pending = readl(gedr);
if (!gedr_v)
continue;
- for (gpio = base; gpio < base + 32; gpio++)
- if (gedr_v & BIT(gpio % 32)) {
- pr_debug("pin %d triggered\n", gpio);
- generic_handle_irq(lnw->irq_base + gpio);
- }
+ while (pending) {
+ gpio = __ffs(pending) - 1;
+ pending &= ~BIT(gpio);
+ generic_handle_irq(lnw->irq_base + base + gpio);
+ }
/* clear the edge detect status bit */
writel(gedr_v, gedr);
}
OpenPOWER on IntegriCloud