[Sound-open-firmware] [PATCH] cnl: dma: refine dma interrupt processing on cnl
From: Rander Wang rander.wang@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@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;
On Mon, 2018-03-05 at 15:13 +0800, Rander Wang wrote:
From: Rander Wang rander.wang@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
This does not apply and should be 2 patches, one for IRQ and one for probe.
Signed-off-by: Rander Wang rander.wang@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 */
The whole handler (an all related CNL funcs) should be in a CONFIG_CANNONLAKE conditional, also use the same name as the existing handler, that way you dont need conditional code later on at IRQ registration.
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;
--------------------------------------------------------------------- Intel Corporation (UK) Limited Registered No. 1134945 (England) Registered Office: Pipers Way, Swindon SN3 1RJ VAT No: 860 2173 47
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
participants (2)
-
Liam Girdwood
-
Rander Wang