summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2009-08-08 23:07:21 +0200
committerEric Miao <eric.y.miao@gmail.com>2009-09-10 18:49:28 +0800
commitd46f5e4a20867da84d12a35407cf7dcc8713c9cc (patch)
treed1eac7ca8e77555f7b4f321becc3ad9726b32980
parent43c6342b1562cc27d8ba1240220cb887ad0e36f0 (diff)
[ARM] pxa/dma: optimize irq handler loop
Reduce loop for dma irq handler callbacks to the minimum required. Since V1: included suggestion from Nicolas Pitre to improve even further the loop. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
-rw-r--r--arch/arm/plat-pxa/dma.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/arch/arm/plat-pxa/dma.c b/arch/arm/plat-pxa/dma.c
index 897663dbc5f4..56b51cf0718b 100644
--- a/arch/arm/plat-pxa/dma.c
+++ b/arch/arm/plat-pxa/dma.c
@@ -94,20 +94,21 @@ EXPORT_SYMBOL(pxa_free_dma);
static irqreturn_t dma_irq_handler(int irq, void *dev_id)
{
int i, dint = DINT;
-
- for (i = 0; i < num_dma_channels; i++) {
- if (dint & (1 << i)) {
- struct dma_channel *channel = &dma_channels[i];
- if (channel->name && channel->irq_handler) {
- channel->irq_handler(i, channel->data);
- } else {
- /*
- * IRQ for an unregistered DMA channel:
- * let's clear the interrupts and disable it.
- */
- printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
- DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
- }
+ struct dma_channel *channel;
+
+ while (dint) {
+ i = __ffs(dint);
+ dint &= (dint - 1);
+ channel = &dma_channels[i];
+ if (channel->name && channel->irq_handler) {
+ channel->irq_handler(i, channel->data);
+ } else {
+ /*
+ * IRQ for an unregistered DMA channel:
+ * let's clear the interrupts and disable it.
+ */
+ printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
+ DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
}
}
return IRQ_HANDLED;