diff mbox series

[16/17] ASoC: SOF: pcm: reset all PCM sources in case of xruns

Message ID 20240402151828.175002-17-pierre-louis.bossart@linux.intel.com
State Accepted
Commit ebd3b3014eebdd490f2c509d79e719fbcc680963
Headers show
Series ASoC: SOF: Intel: improve SoundWire support for LunarLake | expand

Commit Message

Pierre-Louis Bossart April 2, 2024, 3:18 p.m. UTC
With the delayed stops, the xrun handling is problematic: the
applications expects everything to be reset but the firmware and DMA
are still in a PAUSED state.

This patch makes sure the prepare while pending_stop is set is
special-cased.

Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Co-developed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/pcm.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index fbd7e045bcfb..4e11df6b4823 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -221,6 +221,7 @@  static int sof_pcm_prepare(struct snd_soc_component *component,
 			   struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
 	struct snd_sof_pcm *spcm;
 	int ret;
 
@@ -232,8 +233,18 @@  static int sof_pcm_prepare(struct snd_soc_component *component,
 	if (!spcm)
 		return -EINVAL;
 
-	if (spcm->prepared[substream->stream])
-		return 0;
+	if (spcm->prepared[substream->stream]) {
+		if (!spcm->pending_stop[substream->stream])
+			return 0;
+
+		/*
+		 * this case should be reached in case of xruns where we absolutely
+		 * want to free-up and reset all PCM/DMA resources
+		 */
+		ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream, true);
+		if (ret < 0)
+			return ret;
+	}
 
 	dev_dbg(component->dev, "pcm: prepare stream %d dir %d\n",
 		spcm->pcm.pcm_id, substream->stream);