aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/dma.c
diff options
context:
space:
mode:
authorAnuj Aggarwal <anuj.aggarwal@ti.com>2010-03-08 04:35:58 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-05-06 18:02:02 -0400
commita7e05065f562ae347db36b0ef644525cd1e89ecd (patch)
tree02a0144064822f45639462b2ba12559dd32032c9 /arch/arm/mach-davinci/dma.c
parentd154fed7234331dc29240deb04f92f382000e66b (diff)
davinci: edma: clear interrupt status for interrupt enabled channels only
Currently, the ISR in the EDMA driver clears the pending interrupt for all channels without regard to whether that channel has a registered callback or not. This causes problems for devices like DM355/DM365 where the multimedia accelerator uses EDMA by polling on the interrupt pending bits of some of the EDMA channels. Since these channels are actually allocated through the Linux EDMA driver (by an out-of-kernel module), the same shadow region is used by Linux and accelerator. There a race between the Linux ISR and the polling code running on the accelerator on the IPR (interrupt pending register). This patch fixes the issue by making the ISR clear the interrupts only for those channels which have interrupt enabled. The channels which are allocated for the purpose of being polled on by the accelerator will not have a callback function provided and so will not have IER (interrupt enable register) bits set. Tested on DM365 and OMAP-L137/L138 with audio and MMC/SD (as EDMA users). Signed-off-by: Anuj Aggarwal <anuj.aggarwal@ti.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com> CC: Archith John Bency <archith@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-davinci/dma.c')
-rw-r--r--arch/arm/mach-davinci/dma.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 53137387aee1..0bf290befa23 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -359,9 +359,11 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
359 359
360 while (1) { 360 while (1) {
361 int j; 361 int j;
362 if (edma_shadow0_read_array(ctlr, SH_IPR, 0)) 362 if (edma_shadow0_read_array(ctlr, SH_IPR, 0) &
363 edma_shadow0_read_array(ctlr, SH_IER, 0))
363 j = 0; 364 j = 0;
364 else if (edma_shadow0_read_array(ctlr, SH_IPR, 1)) 365 else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) &
366 edma_shadow0_read_array(ctlr, SH_IER, 1))
365 j = 1; 367 j = 1;
366 else 368 else
367 break; 369 break;
@@ -369,8 +371,9 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
369 edma_shadow0_read_array(ctlr, SH_IPR, j)); 371 edma_shadow0_read_array(ctlr, SH_IPR, j));
370 for (i = 0; i < 32; i++) { 372 for (i = 0; i < 32; i++) {
371 int k = (j << 5) + i; 373 int k = (j << 5) + i;
372 if (edma_shadow0_read_array(ctlr, SH_IPR, j) & 374 if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i))
373 (1 << i)) { 375 && (edma_shadow0_read_array(ctlr,
376 SH_IER, j) & BIT(i))) {
374 /* Clear the corresponding IPR bits */ 377 /* Clear the corresponding IPR bits */
375 edma_shadow0_write_array(ctlr, SH_ICR, j, 378 edma_shadow0_write_array(ctlr, SH_ICR, j,
376 (1 << i)); 379 (1 << i));