@@ -406,38 +406,32 @@ static void bcm2835_dma_fill_cb_chain_with_sg(
406
406
}
407
407
}
408
408
409
- static int bcm2835_dma_abort (void __iomem * chan_base )
409
+ static int bcm2835_dma_abort (struct bcm2835_chan * c )
410
410
{
411
- unsigned long cs ;
411
+ void __iomem * chan_base = c -> chan_base ;
412
412
long int timeout = 10000 ;
413
413
414
- cs = readl (chan_base + BCM2835_DMA_CS );
415
- if (!(cs & BCM2835_DMA_ACTIVE ))
414
+ /*
415
+ * A zero control block address means the channel is idle.
416
+ * (The ACTIVE flag in the CS register is not a reliable indicator.)
417
+ */
418
+ if (!readl (chan_base + BCM2835_DMA_ADDR ))
416
419
return 0 ;
417
420
418
421
/* Write 0 to the active bit - Pause the DMA */
419
422
writel (0 , chan_base + BCM2835_DMA_CS );
420
423
421
424
/* Wait for any current AXI transfer to complete */
422
- while ((cs & BCM2835_DMA_ISPAUSED ) && -- timeout ) {
425
+ while ((readl (chan_base + BCM2835_DMA_CS ) &
426
+ BCM2835_DMA_WAITING_FOR_WRITES ) && -- timeout )
423
427
cpu_relax ();
424
- cs = readl (chan_base + BCM2835_DMA_CS );
425
- }
426
428
427
- /* We'll un-pause when we set of our next DMA */
429
+ /* Peripheral might be stuck and fail to signal AXI write responses */
428
430
if (!timeout )
429
- return - ETIMEDOUT ;
430
-
431
- if (!(cs & BCM2835_DMA_ACTIVE ))
432
- return 0 ;
433
-
434
- /* Terminate the control block chain */
435
- writel (0 , chan_base + BCM2835_DMA_NEXTCB );
436
-
437
- /* Abort the whole DMA */
438
- writel (BCM2835_DMA_ABORT | BCM2835_DMA_ACTIVE ,
439
- chan_base + BCM2835_DMA_CS );
431
+ dev_err (c -> vc .chan .device -> dev ,
432
+ "failed to complete outstanding writes\n" );
440
433
434
+ writel (BCM2835_DMA_RESET , chan_base + BCM2835_DMA_CS );
441
435
return 0 ;
442
436
}
443
437
@@ -476,20 +470,23 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
476
470
477
471
spin_lock_irqsave (& c -> vc .lock , flags );
478
472
479
- /* Acknowledge interrupt */
480
- writel (BCM2835_DMA_INT , c -> chan_base + BCM2835_DMA_CS );
473
+ /*
474
+ * Clear the INT flag to receive further interrupts. Keep the channel
475
+ * active in case the descriptor is cyclic or in case the client has
476
+ * already terminated the descriptor and issued a new one. (May happen
477
+ * if this IRQ handler is threaded.) If the channel is finished, it
478
+ * will remain idle despite the ACTIVE flag being set.
479
+ */
480
+ writel (BCM2835_DMA_INT | BCM2835_DMA_ACTIVE ,
481
+ c -> chan_base + BCM2835_DMA_CS );
481
482
482
483
d = c -> desc ;
483
484
484
485
if (d ) {
485
486
if (d -> cyclic ) {
486
487
/* call the cyclic callback */
487
488
vchan_cyclic_callback (& d -> vd );
488
-
489
- /* Keep the DMA engine running */
490
- writel (BCM2835_DMA_ACTIVE ,
491
- c -> chan_base + BCM2835_DMA_CS );
492
- } else {
489
+ } else if (!readl (c -> chan_base + BCM2835_DMA_ADDR )) {
493
490
vchan_cookie_complete (& c -> desc -> vd );
494
491
bcm2835_dma_start_desc (c );
495
492
}
@@ -779,7 +776,6 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
779
776
struct bcm2835_chan * c = to_bcm2835_dma_chan (chan );
780
777
struct bcm2835_dmadev * d = to_bcm2835_dma_dev (c -> vc .chan .device );
781
778
unsigned long flags ;
782
- int timeout = 10000 ;
783
779
LIST_HEAD (head );
784
780
785
781
spin_lock_irqsave (& c -> vc .lock , flags );
@@ -789,27 +785,11 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
789
785
list_del_init (& c -> node );
790
786
spin_unlock (& d -> lock );
791
787
792
- /*
793
- * Stop DMA activity: we assume the callback will not be called
794
- * after bcm_dma_abort() returns (even if it does, it will see
795
- * c->desc is NULL and exit.)
796
- */
788
+ /* stop DMA activity */
797
789
if (c -> desc ) {
798
790
vchan_terminate_vdesc (& c -> desc -> vd );
799
791
c -> desc = NULL ;
800
- bcm2835_dma_abort (c -> chan_base );
801
-
802
- /* Wait for stopping */
803
- while (-- timeout ) {
804
- if (!(readl (c -> chan_base + BCM2835_DMA_CS ) &
805
- BCM2835_DMA_ACTIVE ))
806
- break ;
807
-
808
- cpu_relax ();
809
- }
810
-
811
- if (!timeout )
812
- dev_err (d -> ddev .dev , "DMA transfer could not be terminated\n" );
792
+ bcm2835_dma_abort (c );
813
793
}
814
794
815
795
vchan_get_all_descriptors (& c -> vc , & head );
0 commit comments