summary refs log tree commit diff
path: root/arch/arm/plat-pxa
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 /arch/arm/plat-pxa
parent43c6342b1562cc27d8ba1240220cb887ad0e36f0 (diff)
downloadlinux-d46f5e4a20867da84d12a35407cf7dcc8713c9cc.tar.gz
[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>
Diffstat (limited to 'arch/arm/plat-pxa')
-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;