[Sound-open-firmware] [PATCH] APL: dw-dma: fix interrupt clear
From: Pan Xiuli xiuli.pan@linux.intel.com
Interrupt clear will clear all interrupt bit. If two channel is enabled and when pause/resume one of stream, the two interrupts may happen at same time and one of them will be wrongly cleared.
Signed-off-by: Pan Xiuli xiuli.pan@linux.intel.com
--- Test with: Mininow max rt5651 and UP2 nocodec and CNL nocodec SOF master: da9baf3f3dfef7378ee922620e3a31a04d15504c SOF-Tool master: 86fe688a2b4f68a1ce87e0951686be12a00f1a3c https://github.com/plbossart/sound/tree/topic/sof-v4.14: 33807ca8baa20bab2f98e9cc8a23c51a0822ad9f --- src/drivers/dw-dma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index f16153f..c064330 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -932,9 +932,11 @@ static void dw_dma_irq_handler(void *data) dw_write(dma, DW_CLEAR_ERR, status_err & i); }
+ mask = 0x1 << i; + /* clear interrupts for channel*/ - dw_write(dma, DW_CLEAR_BLOCK, status_block); - dw_write(dma, DW_CLEAR_TFR, status_tfr); + dw_write(dma, DW_CLEAR_BLOCK, status_block & mask); + dw_write(dma, DW_CLEAR_TFR, status_tfr & mask);
/* skip if channel is not running */ if (p->chan[i].status != COMP_STATE_ACTIVE) { @@ -942,7 +944,6 @@ static void dw_dma_irq_handler(void *data) return; }
- mask = 0x1 << i;
#if DW_USE_HW_LLI /* end of a LLI block */
On 2018年05月21日 17:33, Xiuli Pan wrote:
From: Pan Xiuli xiuli.pan@linux.intel.com
Interrupt clear will clear all interrupt bit. If two channel is enabled and when pause/resume one of stream, the two interrupts may happen at same time and one of them will be wrongly cleared.
Signed-off-by: Pan Xiuli xiuli.pan@linux.intel.com
Acked-by: Keyon Jie yang.jie@linux.intel.com
Thanks, ~Keyon
Test with: Mininow max rt5651 and UP2 nocodec and CNL nocodec SOF master: da9baf3f3dfef7378ee922620e3a31a04d15504c SOF-Tool master: 86fe688a2b4f68a1ce87e0951686be12a00f1a3c https://github.com/plbossart/sound/tree/topic/sof-v4.14: 33807ca8baa20bab2f98e9cc8a23c51a0822ad9f
src/drivers/dw-dma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index f16153f..c064330 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -932,9 +932,11 @@ static void dw_dma_irq_handler(void *data) dw_write(dma, DW_CLEAR_ERR, status_err & i); }
- mask = 0x1 << i;
- /* clear interrupts for channel*/
- dw_write(dma, DW_CLEAR_BLOCK, status_block);
- dw_write(dma, DW_CLEAR_TFR, status_tfr);
dw_write(dma, DW_CLEAR_BLOCK, status_block & mask);
dw_write(dma, DW_CLEAR_TFR, status_tfr & mask);
/* skip if channel is not running */ if (p->chan[i].status != COMP_STATE_ACTIVE) {
@@ -942,7 +944,6 @@ static void dw_dma_irq_handler(void *data) return; }
mask = 0x1 << i;
#if DW_USE_HW_LLI /* end of a LLI block */
On Mon, 2018-05-21 at 17:33 +0800, Xiuli Pan wrote:
From: Pan Xiuli xiuli.pan@linux.intel.com
Interrupt clear will clear all interrupt bit. If two channel is enabled and when pause/resume one of stream, the two interrupts may happen at same time and one of them will be wrongly cleared.
Signed-off-by: Pan Xiuli xiuli.pan@linux.intel.com
Applied
Thanks
Liam
participants (3)
-
Keyon Jie
-
Liam Girdwood
-
Xiuli Pan