From ea2fd40a7deead97b168107bbfa39a70c5a0f916 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 28 Oct 2021 11:55:28 -0500 Subject: [PATCH] drivers: Intel: hda-dma: only check DGCS_BUSY with delayed stop When an older kernel is used, we use the immediate stop. On some platforms, we see an -EBUSY error that prevents the trigger stop from working. This patch adds a check to be 'bug-compatible' with previous releases and older kernels. An additional fix would be to insert a poll timeout to make sure the BUSY bit is cleared. BugLink: https://github.com/thesofproject/sof/issues/4919 Fixes: 7e54f456e ('drivers: Intel: hda-dma: ensure DMA channel is idle after stop') Suggested-by: Ranjani Sridharan Signed-off-by: Pierre-Louis Bossart --- src/drivers/intel/hda/hda-dma.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/drivers/intel/hda/hda-dma.c b/src/drivers/intel/hda/hda-dma.c index 0479b7cf9c16..f45858d39bbd 100644 --- a/src/drivers/intel/hda/hda-dma.c +++ b/src/drivers/intel/hda/hda-dma.c @@ -645,6 +645,7 @@ static int hda_dma_release(struct dma_chan_data *channel) static int hda_dma_stop_common(struct dma_chan_data *channel) { + struct dai_data *dd = channel->dev_data; struct hda_chan_data *hda_chan; uint32_t flags, dgcs; @@ -668,12 +669,14 @@ static int hda_dma_stop_common(struct dma_chan_data *channel) } /* check if channel is idle. No need to wait after clearing the GEN bit */ - dgcs = dma_chan_reg_read(channel, DGCS); - if (dgcs & DGCS_GBUSY) { - tr_err(&hdma_tr, "hda-dmac: %d channel %d not idle after stop", - channel->dma->plat_data.id, channel->index); - irq_local_enable(flags); - return -EBUSY; + if (dd && dd->delayed_dma_stop) { + dgcs = dma_chan_reg_read(channel, DGCS); + if (dgcs & DGCS_GBUSY) { + tr_err(&hdma_tr, "hda-dmac: %d channel %d not idle after stop", + channel->dma->plat_data.id, channel->index); + irq_local_enable(flags); + return -EBUSY; + } } channel->status = COMP_STATE_PREPARE; hda_chan = dma_chan_get_data(channel);