@@ -282,7 +282,7 @@ void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan)
282
282
/* Disable BDMA channel interrupts */
283
283
iowrite32 (0 , bdma_chan -> regs + TSI721_DMAC_INTE );
284
284
if (bdma_chan -> active )
285
- tasklet_schedule (& bdma_chan -> tasklet );
285
+ tasklet_hi_schedule (& bdma_chan -> tasklet );
286
286
}
287
287
288
288
#ifdef CONFIG_PCI_MSI
@@ -298,7 +298,7 @@ static irqreturn_t tsi721_bdma_msix(int irq, void *ptr)
298
298
struct tsi721_bdma_chan * bdma_chan = ptr ;
299
299
300
300
if (bdma_chan -> active )
301
- tasklet_schedule (& bdma_chan -> tasklet );
301
+ tasklet_hi_schedule (& bdma_chan -> tasklet );
302
302
return IRQ_HANDLED ;
303
303
}
304
304
#endif /* CONFIG_PCI_MSI */
@@ -584,13 +584,71 @@ static void tsi721_dma_tasklet(unsigned long data)
584
584
iowrite32 (dmac_int , bdma_chan -> regs + TSI721_DMAC_INT );
585
585
586
586
if (dmac_int & TSI721_DMAC_INT_ERR ) {
587
+ int i = 10000 ;
588
+ struct tsi721_tx_desc * desc ;
589
+
590
+ desc = bdma_chan -> active_tx ;
587
591
dmac_sts = ioread32 (bdma_chan -> regs + TSI721_DMAC_STS );
588
592
tsi_err (& bdma_chan -> dchan .dev -> device ,
589
- "ERR - DMAC%d_STS = 0x%x" ,
590
- bdma_chan -> id , dmac_sts );
593
+ "DMAC%d_STS = 0x%x did=%d raddr=0x%llx" ,
594
+ bdma_chan -> id , dmac_sts , desc -> destid , desc -> rio_addr );
595
+
596
+ /* Re-initialize DMA channel if possible */
597
+
598
+ if ((dmac_sts & TSI721_DMAC_STS_ABORT ) == 0 )
599
+ goto err_out ;
600
+
601
+ tsi721_clr_stat (bdma_chan );
591
602
592
603
spin_lock (& bdma_chan -> lock );
604
+
605
+ /* Put DMA channel into init state */
606
+ iowrite32 (TSI721_DMAC_CTL_INIT ,
607
+ bdma_chan -> regs + TSI721_DMAC_CTL );
608
+ do {
609
+ udelay (1 );
610
+ dmac_sts = ioread32 (bdma_chan -> regs + TSI721_DMAC_STS );
611
+ i -- ;
612
+ } while ((dmac_sts & TSI721_DMAC_STS_ABORT ) && i );
613
+
614
+ if (dmac_sts & TSI721_DMAC_STS_ABORT ) {
615
+ tsi_err (& bdma_chan -> dchan .dev -> device ,
616
+ "Failed to re-initiate DMAC%d" , bdma_chan -> id );
617
+ spin_unlock (& bdma_chan -> lock );
618
+ goto err_out ;
619
+ }
620
+
621
+ /* Setup DMA descriptor pointers */
622
+ iowrite32 (((u64 )bdma_chan -> bd_phys >> 32 ),
623
+ bdma_chan -> regs + TSI721_DMAC_DPTRH );
624
+ iowrite32 (((u64 )bdma_chan -> bd_phys & TSI721_DMAC_DPTRL_MASK ),
625
+ bdma_chan -> regs + TSI721_DMAC_DPTRL );
626
+
627
+ /* Setup descriptor status FIFO */
628
+ iowrite32 (((u64 )bdma_chan -> sts_phys >> 32 ),
629
+ bdma_chan -> regs + TSI721_DMAC_DSBH );
630
+ iowrite32 (((u64 )bdma_chan -> sts_phys & TSI721_DMAC_DSBL_MASK ),
631
+ bdma_chan -> regs + TSI721_DMAC_DSBL );
632
+ iowrite32 (TSI721_DMAC_DSSZ_SIZE (bdma_chan -> sts_size ),
633
+ bdma_chan -> regs + TSI721_DMAC_DSSZ );
634
+
635
+ /* Clear interrupt bits */
636
+ iowrite32 (TSI721_DMAC_INT_ALL ,
637
+ bdma_chan -> regs + TSI721_DMAC_INT );
638
+
639
+ ioread32 (bdma_chan -> regs + TSI721_DMAC_INT );
640
+
641
+ bdma_chan -> wr_count = bdma_chan -> wr_count_next = 0 ;
642
+ bdma_chan -> sts_rdptr = 0 ;
643
+ udelay (10 );
644
+
645
+ desc = bdma_chan -> active_tx ;
646
+ desc -> status = DMA_ERROR ;
647
+ dma_cookie_complete (& desc -> txd );
648
+ list_add (& desc -> desc_node , & bdma_chan -> free_list );
593
649
bdma_chan -> active_tx = NULL ;
650
+ if (bdma_chan -> active )
651
+ tsi721_advance_work (bdma_chan , NULL );
594
652
spin_unlock (& bdma_chan -> lock );
595
653
}
596
654
@@ -619,16 +677,19 @@ static void tsi721_dma_tasklet(unsigned long data)
619
677
}
620
678
list_add (& desc -> desc_node , & bdma_chan -> free_list );
621
679
bdma_chan -> active_tx = NULL ;
622
- tsi721_advance_work (bdma_chan , NULL );
680
+ if (bdma_chan -> active )
681
+ tsi721_advance_work (bdma_chan , NULL );
623
682
spin_unlock (& bdma_chan -> lock );
624
683
if (callback )
625
684
callback (param );
626
685
} else {
627
- tsi721_advance_work (bdma_chan , bdma_chan -> active_tx );
686
+ if (bdma_chan -> active )
687
+ tsi721_advance_work (bdma_chan ,
688
+ bdma_chan -> active_tx );
628
689
spin_unlock (& bdma_chan -> lock );
629
690
}
630
691
}
631
-
692
+ err_out :
632
693
/* Re-Enable BDMA channel interrupts */
633
694
iowrite32 (TSI721_DMAC_INT_ALL , bdma_chan -> regs + TSI721_DMAC_INTE );
634
695
}
@@ -841,7 +902,6 @@ static int tsi721_terminate_all(struct dma_chan *dchan)
841
902
{
842
903
struct tsi721_bdma_chan * bdma_chan = to_tsi721_chan (dchan );
843
904
struct tsi721_tx_desc * desc , * _d ;
844
- u32 dmac_int ;
845
905
LIST_HEAD (list );
846
906
847
907
tsi_debug (DMA , & dchan -> dev -> device , "DMAC%d" , bdma_chan -> id );
@@ -850,7 +910,10 @@ static int tsi721_terminate_all(struct dma_chan *dchan)
850
910
851
911
bdma_chan -> active = false;
852
912
853
- if (!tsi721_dma_is_idle (bdma_chan )) {
913
+ while (!tsi721_dma_is_idle (bdma_chan )) {
914
+
915
+ udelay (5 );
916
+ #if (0 )
854
917
/* make sure to stop the transfer */
855
918
iowrite32 (TSI721_DMAC_CTL_SUSP ,
856
919
bdma_chan -> regs + TSI721_DMAC_CTL );
@@ -859,6 +922,7 @@ static int tsi721_terminate_all(struct dma_chan *dchan)
859
922
do {
860
923
dmac_int = ioread32 (bdma_chan -> regs + TSI721_DMAC_INT );
861
924
} while ((dmac_int & TSI721_DMAC_INT_SUSP ) == 0 );
925
+ #endif
862
926
}
863
927
864
928
if (bdma_chan -> active_tx )
0 commit comments