[Sound-open-firmware] [PATCH] cnl: dma: refine dma interrupt processing on cnl

Rander Wang rander.wang at linux.intel.com
Mon Mar 5 08:13:54 CET 2018


From: Rander Wang <rander.wang at intel.com>

On cnl, all the dma share the same interrupt pin, so
all the dma controller need to be checked in interrupt
function. And also refine dma probe

Signed-off-by: Rander Wang <rander.wang at linux.intel.com>
---
 src/drivers/dw-dma.c               | 61 +++++++++++++++++++++-----------------
 src/platform/cannonlake/platform.c |  5 ++++
 2 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c
index 15d608c..a06087e 100644
--- a/src/drivers/dw-dma.c
+++ b/src/drivers/dw-dma.c
@@ -1029,7 +1029,6 @@ static int dw_dma_probe(struct dma *dma)
 }
 
 #else
-
 /* this will probably be called at the end of every period copied */
 static void dw_dma_irq_handler(void *data)
 {
@@ -1047,14 +1046,7 @@ static void dw_dma_irq_handler(void *data)
 
 	status_intr = dw_read(dma, DW_INTR_STATUS);
 	if (!status_intr) {
-#ifdef CONFIG_CANNONLAKE
-		dma++;
-		status_intr = dw_read(dma, DW_INTR_STATUS);
-		if (!status_intr)
-			trace_dma_error("eI0");
-#else
 		trace_dma_error("eI0");
-#endif
 	}
 
 	tracev_dma("DIr");
@@ -1144,37 +1136,52 @@ static void dw_dma_irq_handler(void *data)
 	}
 }
 
+/*All the dma share the same interrupt on CNL, so check each dma*/
+/*controller when interrupt coming, then do the work            */
+static void dw_dma_irq_cnl(void *data)
+{
+	struct dma *dma;
+	uint32_t status_intr;
+
+	/*check interrupt status of DMA controller 0*/
+	dma = dma_get(DMA_GP_LP_DMAC0);
+	status_intr = dw_read(dma, DW_INTR_STATUS);
+	if (status_intr)
+		dw_dma_irq_handler(dma);
+
+	/*check interrupt status of DMA controller 1*/
+	dma = dma_get(DMA_GP_LP_DMAC1);
+	status_intr = dw_read(dma, DW_INTR_STATUS);
+	if (status_intr)
+		dw_dma_irq_handler(dma);
+}
+
 static int dw_dma_probe(struct dma *dma)
 {
 	struct dma_pdata *dw_pdata;
-	struct dma *dmac = dma;
 	int i;
-#ifdef CONFIG_CANNONLAKE
-	int j;
-
-	for (j = 0; j < MAX_GPDMA_COUNT; j++)
-#endif
-	{
-		/* allocate private data */
-		dw_pdata = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*dw_pdata));
-		dma_set_drvdata(dmac, dw_pdata);
 
-		spinlock_init(&dmac->lock);
+	/* allocate private data */
+	dw_pdata = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*dw_pdata));
+	dma_set_drvdata(dma, dw_pdata);
 
-		dw_dma_setup(dmac);
+	spinlock_init(&dma->lock);
 
-		/* init work */
-		for (i = 0; i < DW_MAX_CHAN; i++) {
-			dw_pdata->chan[i].dma = dmac;
-			dw_pdata->chan[i].channel = i;
-			dw_pdata->chan[i].status = COMP_STATE_INIT;
-		}
+	dw_dma_setup(dma);
 
-		dmac++;
+	/* init work */
+	for (i = 0; i < DW_MAX_CHAN; i++) {
+		dw_pdata->chan[i].dma = dma;
+		dw_pdata->chan[i].channel = i;
+		dw_pdata->chan[i].status = COMP_STATE_INIT;
 	}
 
 	/* register our IRQ handler */
+#ifdef CONFIG_CANNONLAKE
+	interrupt_register(dma_irq(dma), dw_dma_irq_cnl, dma);
+#else
 	interrupt_register(dma_irq(dma), dw_dma_irq_handler, dma);
+#endif
 	interrupt_enable(dma_irq(dma));
 
 	return 0;
diff --git a/src/platform/cannonlake/platform.c b/src/platform/cannonlake/platform.c
index beb6582..1a9b88a 100644
--- a/src/platform/cannonlake/platform.c
+++ b/src/platform/cannonlake/platform.c
@@ -253,6 +253,11 @@ int platform_init(struct reef *reef)
 		return -ENODEV;
 	dma_probe(dmac);
 
+	dmac = dma_get(DMA_GP_LP_DMAC1);
+	if (!dmac)
+		return -ENODEV;
+	dma_probe(dmac);
+
 	dmac = dma_get(DMA_HOST_OUT_DMAC);
 	if (!dmac)
 		return -ENODEV;
-- 
2.14.1



More information about the Sound-open-firmware mailing list