@@ -50,6 +50,83 @@ static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
50
50
return IRQ_HANDLED ;
51
51
}
52
52
53
+ static void fsl_edma3_err_check (struct fsl_edma_chan * fsl_chan )
54
+ {
55
+ unsigned int ch_err ;
56
+ u32 val ;
57
+
58
+ scoped_guard (spinlock , & fsl_chan -> vchan .lock ) {
59
+ ch_err = edma_readl_chreg (fsl_chan , ch_es );
60
+ if (!(ch_err & EDMA_V3_CH_ERR ))
61
+ return ;
62
+
63
+ edma_writel_chreg (fsl_chan , EDMA_V3_CH_ERR , ch_es );
64
+ val = edma_readl_chreg (fsl_chan , ch_csr );
65
+ val &= ~EDMA_V3_CH_CSR_ERQ ;
66
+ edma_writel_chreg (fsl_chan , val , ch_csr );
67
+ }
68
+
69
+ /* Ignore this interrupt since channel has been disabled already */
70
+ if (!fsl_chan -> edesc )
71
+ return ;
72
+
73
+ if (ch_err & EDMA_V3_CH_ERR_DBE )
74
+ dev_err (& fsl_chan -> pdev -> dev , "Destination Bus Error interrupt.\n" );
75
+
76
+ if (ch_err & EDMA_V3_CH_ERR_SBE )
77
+ dev_err (& fsl_chan -> pdev -> dev , "Source Bus Error interrupt.\n" );
78
+
79
+ if (ch_err & EDMA_V3_CH_ERR_SGE )
80
+ dev_err (& fsl_chan -> pdev -> dev , "Scatter/Gather Configuration Error interrupt.\n" );
81
+
82
+ if (ch_err & EDMA_V3_CH_ERR_NCE )
83
+ dev_err (& fsl_chan -> pdev -> dev , "NBYTES/CITER Configuration Error interrupt.\n" );
84
+
85
+ if (ch_err & EDMA_V3_CH_ERR_DOE )
86
+ dev_err (& fsl_chan -> pdev -> dev , "Destination Offset Error interrupt.\n" );
87
+
88
+ if (ch_err & EDMA_V3_CH_ERR_DAE )
89
+ dev_err (& fsl_chan -> pdev -> dev , "Destination Address Error interrupt.\n" );
90
+
91
+ if (ch_err & EDMA_V3_CH_ERR_SOE )
92
+ dev_err (& fsl_chan -> pdev -> dev , "Source Offset Error interrupt.\n" );
93
+
94
+ if (ch_err & EDMA_V3_CH_ERR_SAE )
95
+ dev_err (& fsl_chan -> pdev -> dev , "Source Address Error interrupt.\n" );
96
+
97
+ if (ch_err & EDMA_V3_CH_ERR_ECX )
98
+ dev_err (& fsl_chan -> pdev -> dev , "Transfer Canceled interrupt.\n" );
99
+
100
+ if (ch_err & EDMA_V3_CH_ERR_UCE )
101
+ dev_err (& fsl_chan -> pdev -> dev , "Uncorrectable TCD error during channel execution interrupt.\n" );
102
+
103
+ fsl_chan -> status = DMA_ERROR ;
104
+ }
105
+
106
+ static irqreturn_t fsl_edma3_err_handler_per_chan (int irq , void * dev_id )
107
+ {
108
+ struct fsl_edma_chan * fsl_chan = dev_id ;
109
+
110
+ fsl_edma3_err_check (fsl_chan );
111
+
112
+ return IRQ_HANDLED ;
113
+ }
114
+
115
+ static irqreturn_t fsl_edma3_err_handler_shared (int irq , void * dev_id )
116
+ {
117
+ struct fsl_edma_engine * fsl_edma = dev_id ;
118
+ unsigned int ch ;
119
+
120
+ for (ch = 0 ; ch < fsl_edma -> n_chans ; ch ++ ) {
121
+ if (fsl_edma -> chan_masked & BIT (ch ))
122
+ continue ;
123
+
124
+ fsl_edma3_err_check (& fsl_edma -> chans [ch ]);
125
+ }
126
+
127
+ return IRQ_HANDLED ;
128
+ }
129
+
53
130
static irqreturn_t fsl_edma3_tx_handler (int irq , void * dev_id )
54
131
{
55
132
struct fsl_edma_chan * fsl_chan = dev_id ;
@@ -309,7 +386,8 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma
309
386
310
387
static int fsl_edma3_irq_init (struct platform_device * pdev , struct fsl_edma_engine * fsl_edma )
311
388
{
312
- int i ;
389
+ char * errirq_name ;
390
+ int i , ret ;
313
391
314
392
for (i = 0 ; i < fsl_edma -> n_chans ; i ++ ) {
315
393
@@ -324,6 +402,27 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi
324
402
return - EINVAL ;
325
403
326
404
fsl_chan -> irq_handler = fsl_edma3_tx_handler ;
405
+
406
+ if (!(fsl_edma -> drvdata -> flags & FSL_EDMA_DRV_ERRIRQ_SHARE )) {
407
+ fsl_chan -> errirq = fsl_chan -> txirq ;
408
+ fsl_chan -> errirq_handler = fsl_edma3_err_handler_per_chan ;
409
+ }
410
+ }
411
+
412
+ /* All channel err use one irq number */
413
+ if (fsl_edma -> drvdata -> flags & FSL_EDMA_DRV_ERRIRQ_SHARE ) {
414
+ /* last one is error irq */
415
+ fsl_edma -> errirq = platform_get_irq_optional (pdev , fsl_edma -> n_chans );
416
+ if (fsl_edma -> errirq < 0 )
417
+ return 0 ; /* dts miss err irq, treat as no err irq case */
418
+
419
+ errirq_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s-err" ,
420
+ dev_name (& pdev -> dev ));
421
+
422
+ ret = devm_request_irq (& pdev -> dev , fsl_edma -> errirq , fsl_edma3_err_handler_shared ,
423
+ 0 , errirq_name , fsl_edma );
424
+ if (ret )
425
+ return dev_err_probe (& pdev -> dev , ret , "Can't register eDMA err IRQ.\n" );
327
426
}
328
427
329
428
return 0 ;
@@ -464,7 +563,8 @@ static struct fsl_edma_drvdata imx7ulp_data = {
464
563
};
465
564
466
565
static struct fsl_edma_drvdata imx8qm_data = {
467
- .flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE ,
566
+ .flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE
567
+ | FSL_EDMA_DRV_ERRIRQ_SHARE ,
468
568
.chreg_space_sz = 0x10000 ,
469
569
.chreg_off = 0x10000 ,
470
570
.setup_irq = fsl_edma3_irq_init ,
@@ -481,14 +581,15 @@ static struct fsl_edma_drvdata imx8ulp_data = {
481
581
};
482
582
483
583
static struct fsl_edma_drvdata imx93_data3 = {
484
- .flags = FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3 ,
584
+ .flags = FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_ERRIRQ_SHARE ,
485
585
.chreg_space_sz = 0x10000 ,
486
586
.chreg_off = 0x10000 ,
487
587
.setup_irq = fsl_edma3_irq_init ,
488
588
};
489
589
490
590
static struct fsl_edma_drvdata imx93_data4 = {
491
- .flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4 ,
591
+ .flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4
592
+ | FSL_EDMA_DRV_ERRIRQ_SHARE ,
492
593
.chreg_space_sz = 0x8000 ,
493
594
.chreg_off = 0x10000 ,
494
595
.mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg , ch_mux ),
@@ -498,7 +599,7 @@ static struct fsl_edma_drvdata imx93_data4 = {
498
599
499
600
static struct fsl_edma_drvdata imx95_data5 = {
500
601
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4 |
501
- FSL_EDMA_DRV_TCD64 ,
602
+ FSL_EDMA_DRV_TCD64 | FSL_EDMA_DRV_ERRIRQ_SHARE ,
502
603
.chreg_space_sz = 0x8000 ,
503
604
.chreg_off = 0x10000 ,
504
605
.mux_off = 0x200 ,
@@ -700,6 +801,9 @@ static int fsl_edma_probe(struct platform_device *pdev)
700
801
snprintf (fsl_chan -> chan_name , sizeof (fsl_chan -> chan_name ), "%s-CH%02d" ,
701
802
dev_name (& pdev -> dev ), i );
702
803
804
+ snprintf (fsl_chan -> errirq_name , sizeof (fsl_chan -> errirq_name ),
805
+ "%s-CH%02d-err" , dev_name (& pdev -> dev ), i );
806
+
703
807
fsl_chan -> edma = fsl_edma ;
704
808
fsl_chan -> pm_state = RUNNING ;
705
809
fsl_chan -> srcid = 0 ;
0 commit comments