[ARM] pxa/dma: optimize irq handler loop
authorRobert Jarzmik <robert.jarzmik@free.fr>
Sat, 8 Aug 2009 21:07:21 +0000 (23:07 +0200)
committerEric Miao <eric.y.miao@gmail.com>
Thu, 10 Sep 2009 10:49:28 +0000 (18:49 +0800)
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>
arch/arm/plat-pxa/dma.c

index 897663d..56b51cf 100644 (file)
@@ -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;