diff options
author | eric miao <eric.miao@marvell.com> | 2008-03-03 21:57:18 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-04-19 06:29:03 -0400 |
commit | 7a26d3a33fd9adcbfd4fa2ca2d7e8a8272817935 (patch) | |
tree | 2e0aac15ed22525880dcf35f23cd60f7bd098a96 /arch/arm/mach-pxa/irq.c | |
parent | d72b1370b0b45f1fabda5ae4d603773d8a2c226a (diff) |
[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 = { | |||
178 | * Demux handler for GPIO>=2 edge detect interrupts | 178 | * Demux handler for GPIO>=2 edge detect interrupts |
179 | */ | 179 | */ |
180 | 180 | ||
181 | #define GEDR_BITS (sizeof(gedr) * BITS_PER_BYTE) | ||
182 | |||
181 | static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | 183 | static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) |
182 | { | 184 | { |
183 | unsigned int mask; | 185 | int loop, bit, n; |
184 | int loop; | 186 | unsigned long gedr[4]; |
185 | 187 | ||
186 | do { | 188 | do { |
187 | loop = 0; | 189 | gedr[0] = GEDR0 & GPIO_IRQ_mask[0] & ~3; |
190 | gedr[1] = GEDR1 & GPIO_IRQ_mask[1]; | ||
191 | gedr[2] = GEDR2 & GPIO_IRQ_mask[2]; | ||
192 | gedr[3] = GEDR3 & GPIO_IRQ_mask[3]; | ||
188 | 193 | ||
189 | mask = GEDR0 & GPIO_IRQ_mask[0] & ~3; | 194 | GEDR0 = gedr[0]; GEDR1 = gedr[1]; |
190 | if (mask) { | 195 | GEDR2 = gedr[2]; GEDR3 = gedr[3]; |
191 | GEDR0 = mask; | ||
192 | irq = IRQ_GPIO(2); | ||
193 | desc = irq_desc + irq; | ||
194 | mask >>= 2; | ||
195 | do { | ||
196 | if (mask & 1) | ||
197 | desc_handle_irq(irq, desc); | ||
198 | irq++; | ||
199 | desc++; | ||
200 | mask >>= 1; | ||
201 | } while (mask); | ||
202 | loop = 1; | ||
203 | } | ||
204 | 196 | ||
205 | mask = GEDR1 & GPIO_IRQ_mask[1]; | 197 | loop = 0; |
206 | if (mask) { | 198 | bit = find_first_bit(gedr, GEDR_BITS); |
207 | GEDR1 = mask; | 199 | while (bit < GEDR_BITS) { |
208 | irq = IRQ_GPIO(32); | ||
209 | desc = irq_desc + irq; | ||
210 | do { | ||
211 | if (mask & 1) | ||
212 | desc_handle_irq(irq, desc); | ||
213 | irq++; | ||
214 | desc++; | ||
215 | mask >>= 1; | ||
216 | } while (mask); | ||
217 | loop = 1; | 200 | loop = 1; |
218 | } | ||
219 | 201 | ||
220 | mask = GEDR2 & GPIO_IRQ_mask[2]; | 202 | n = PXA_GPIO_IRQ_BASE + bit; |
221 | if (mask) { | 203 | desc_handle_irq(n, irq_desc + n); |
222 | GEDR2 = mask; | ||
223 | irq = IRQ_GPIO(64); | ||
224 | desc = irq_desc + irq; | ||
225 | do { | ||
226 | if (mask & 1) | ||
227 | desc_handle_irq(irq, desc); | ||
228 | irq++; | ||
229 | desc++; | ||
230 | mask >>= 1; | ||
231 | } while (mask); | ||
232 | loop = 1; | ||
233 | } | ||
234 | 204 | ||
235 | mask = GEDR3 & GPIO_IRQ_mask[3]; | 205 | bit = find_next_bit(gedr, GEDR_BITS, bit + 1); |
236 | if (mask) { | ||
237 | GEDR3 = mask; | ||
238 | irq = IRQ_GPIO(96); | ||
239 | desc = irq_desc + irq; | ||
240 | do { | ||
241 | if (mask & 1) | ||
242 | desc_handle_irq(irq, desc); | ||
243 | irq++; | ||
244 | desc++; | ||
245 | mask >>= 1; | ||
246 | } while (mask); | ||
247 | loop = 1; | ||
248 | } | 206 | } |
249 | } while (loop); | 207 | } while (loop); |
250 | } | 208 | } |