aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-davinci/dma.c69
1 files changed, 34 insertions, 35 deletions
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index fd33919c95d4..8713694a6f2c 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -353,9 +353,10 @@ static int irq2ctlr(int irq)
353 *****************************************************************************/ 353 *****************************************************************************/
354static irqreturn_t dma_irq_handler(int irq, void *data) 354static irqreturn_t dma_irq_handler(int irq, void *data)
355{ 355{
356 int i;
357 int ctlr; 356 int ctlr;
358 unsigned int cnt = 0; 357 u32 sh_ier;
358 u32 sh_ipr;
359 u32 bank;
359 360
360 ctlr = irq2ctlr(irq); 361 ctlr = irq2ctlr(irq);
361 if (ctlr < 0) 362 if (ctlr < 0)
@@ -363,41 +364,39 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
363 364
364 dev_dbg(data, "dma_irq_handler\n"); 365 dev_dbg(data, "dma_irq_handler\n");
365 366
366 if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) && 367 sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0);
367 (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0)) 368 if (!sh_ipr) {
368 return IRQ_NONE; 369 sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1);
370 if (!sh_ipr)
371 return IRQ_NONE;
372 sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1);
373 bank = 1;
374 } else {
375 sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0);
376 bank = 0;
377 }
369 378
370 while (1) { 379 do {
371 int j; 380 u32 slot;
372 if (edma_shadow0_read_array(ctlr, SH_IPR, 0) & 381 u32 channel;
373 edma_shadow0_read_array(ctlr, SH_IER, 0)) 382
374 j = 0; 383 dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr);
375 else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) & 384
376 edma_shadow0_read_array(ctlr, SH_IER, 1)) 385 slot = __ffs(sh_ipr);
377 j = 1; 386 sh_ipr &= ~(BIT(slot));
378 else 387
379 break; 388 if (sh_ier & BIT(slot)) {
380 dev_dbg(data, "IPR%d %08x\n", j, 389 channel = (bank << 5) | slot;
381 edma_shadow0_read_array(ctlr, SH_IPR, j)); 390 /* Clear the corresponding IPR bits */
382 for (i = 0; i < 32; i++) { 391 edma_shadow0_write_array(ctlr, SH_ICR, bank,
383 int k = (j << 5) + i; 392 BIT(slot));
384 if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i)) 393 if (edma_cc[ctlr]->intr_data[channel].callback)
385 && (edma_shadow0_read_array(ctlr, 394 edma_cc[ctlr]->intr_data[channel].callback(
386 SH_IER, j) & BIT(i))) { 395 channel, DMA_COMPLETE,
387 /* Clear the corresponding IPR bits */ 396 edma_cc[ctlr]->intr_data[channel].data);
388 edma_shadow0_write_array(ctlr, SH_ICR, j,
389 BIT(i));
390 if (edma_cc[ctlr]->intr_data[k].callback)
391 edma_cc[ctlr]->intr_data[k].callback(
392 k, DMA_COMPLETE,
393 edma_cc[ctlr]->intr_data[k].
394 data);
395 }
396 } 397 }
397 cnt++; 398 } while (sh_ipr);
398 if (cnt > 10) 399
399 break;
400 }
401 edma_shadow0_write(ctlr, SH_IEVAL, 1); 400 edma_shadow0_write(ctlr, SH_IEVAL, 1);
402 return IRQ_HANDLED; 401 return IRQ_HANDLED;
403} 402}