summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxc/gpio.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-02-08 21:02:30 +0100
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-02-24 10:06:57 +0100
commit3621f188b945a9f9bc1387115834041b7a4619e0 (patch)
tree6ad70878e56e3be6db728e9a0341ddfe22c5d477 /arch/arm/plat-mxc/gpio.c
parent3244c3e7797d235250cd01d4a1d3f60b3b2f6261 (diff)
arm/imx/gpio: use fls to find set bits in the irq status register
As in most cases only few irqs are pending using fls is more effective than looping over all bits. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Diffstat (limited to 'arch/arm/plat-mxc/gpio.c')
-rw-r--r--arch/arm/plat-mxc/gpio.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index bee100b7e93..0b11554dada 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -154,24 +154,22 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
__raw_writel(val | (edge << (bit << 1)), reg);
}
-/* handle n interrupts in one status register */
+/* handle 32 interrupts in one status register */
static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
{
- u32 gpio_irq_no;
+ u32 gpio_irq_no_base = port->virtual_irq_start;
- gpio_irq_no = port->virtual_irq_start;
- for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) {
- u32 gpio = irq_to_gpio(gpio_irq_no);
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
- if ((irq_stat & 1) == 0)
- continue;
+ BUG_ON(!(irq_desc[gpio_irq_no_base + irqoffset].handle_irq));
- BUG_ON(!(irq_desc[gpio_irq_no].handle_irq));
+ if (port->both_edges & (1 << irqoffset))
+ mxc_flip_edge(port, irqoffset);
- if (port->both_edges & (1 << (gpio & 31)))
- mxc_flip_edge(port, gpio);
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
- generic_handle_irq(gpio_irq_no);
+ irq_stat &= ~(1 << irqoffset);
}
}