diff options
author | eric miao <eric.miao@marvell.com> | 2008-03-04 05:57:18 +0300 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-04-19 14:29:03 +0400 |
commit | 7a26d3a33fd9adcbfd4fa2ca2d7e8a8272817935 (patch) | |
tree | 2e0aac15ed22525880dcf35f23cd60f7bd098a96 /arch/arm/mach-pxa/irq.c | |
parent | d72b1370b0b45f1fabda5ae4d603773d8a2c226a (diff) | |
download | linux-7a26d3a33fd9adcbfd4fa2ca2d7e8a8272817935.tar.xz |
[ARM] pxa: generalize the muxed gpio IRQ handling code with loop and ffs()
1. As David Brownell suggests, using ffs() is going to make the loop
a bit faster (by avoiding unnecessary shift and iteration)
2. Russell suggested find_{first,next}_bit() being used with the
gedr[] array
Signed-off-by: eric miao <eric.miao@marvell.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pxa/irq.c')
-rw-r--r-- | arch/arm/mach-pxa/irq.c | 74 |
1 files changed, 16 insertions, 58 deletions
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 36c6a68beca2..381fde66aeeb 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -178,73 +178,31 @@ static struct irq_chip pxa_low_gpio_chip = { * Demux handler for GPIO>=2 edge detect interrupts */ +#define GEDR_BITS (sizeof(gedr) * BITS_PER_BYTE) + static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) { - unsigned int mask; - int loop; + int loop, bit, n; + unsigned long gedr[4]; do { - loop = 0; + gedr[0] = GEDR0 & GPIO_IRQ_mask[0] & ~3; + gedr[1] = GEDR1 & GPIO_IRQ_mask[1]; + gedr[2] = GEDR2 & GPIO_IRQ_mask[2]; + gedr[3] = GEDR3 & GPIO_IRQ_mask[3]; - mask = GEDR0 & GPIO_IRQ_mask[0] & ~3; - if (mask) { - GEDR0 = mask; - irq = IRQ_GPIO(2); - desc = irq_desc + irq; - mask >>= 2; - do { - if (mask & 1) - desc_handle_irq(irq, desc); - irq++; - desc++; - mask >>= 1; - } while (mask); - loop = 1; - } + GEDR0 = gedr[0]; GEDR1 = gedr[1]; + GEDR2 = gedr[2]; GEDR3 = gedr[3]; - mask = GEDR1 & GPIO_IRQ_mask[1]; - if (mask) { - GEDR1 = mask; - irq = IRQ_GPIO(32); - desc = irq_desc + irq; - do { - if (mask & 1) - desc_handle_irq(irq, desc); - irq++; - desc++; - mask >>= 1; - } while (mask); + loop = 0; + bit = find_first_bit(gedr, GEDR_BITS); + while (bit < GEDR_BITS) { loop = 1; - } - mask = GEDR2 & GPIO_IRQ_mask[2]; - if (mask) { - GEDR2 = mask; - irq = IRQ_GPIO(64); - desc = irq_desc + irq; - do { - if (mask & 1) - desc_handle_irq(irq, desc); - irq++; - desc++; - mask >>= 1; - } while (mask); - loop = 1; - } + n = PXA_GPIO_IRQ_BASE + bit; + desc_handle_irq(n, irq_desc + n); - mask = GEDR3 & GPIO_IRQ_mask[3]; - if (mask) { - GEDR3 = mask; - irq = IRQ_GPIO(96); - desc = irq_desc + irq; - do { - if (mask & 1) - desc_handle_irq(irq, desc); - irq++; - desc++; - mask >>= 1; - } while (mask); - loop = 1; + bit = find_next_bit(gedr, GEDR_BITS, bit + 1); } } while (loop); } |