diff options
author | Robert Jarzmik <robert.jarzmik@free.fr> | 2009-08-08 23:07:21 +0200 |
---|---|---|
committer | Eric Miao <eric.y.miao@gmail.com> | 2009-09-10 18:49:28 +0800 |
commit | d46f5e4a20867da84d12a35407cf7dcc8713c9cc (patch) | |
tree | d1eac7ca8e77555f7b4f321becc3ad9726b32980 /arch | |
parent | 43c6342b1562cc27d8ba1240220cb887ad0e36f0 (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/plat-pxa/dma.c | 29 |
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; |