From 732063b92bb727b27e61580ce278dddefe31c6ad Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Thu, 17 Mar 2011 19:32:55 +0000
Subject: [PATCH] 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>
---
 drivers/gpio/langwell_gpio.c | 13 +++++++------
 1 file 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)
 	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);
 	}
-- 
GitLab