diff mbox series

[15/17] ASoC: SOF: pcm: add pending_stop state variable

Message ID 20240402151828.175002-16-pierre-louis.bossart@linux.intel.com
State Accepted
Commit dbc78bce74f5f9057ba02bdc8d1549d24c573900
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
Add a state variable to keep track of delayed stops, in case
pcm_ops->platform_stop_during_hw_free is set.

This patch should be iso-functionality, possibly removing no-op
cases. The main purpose of this new state variable is to prepare a
follow-up patch to reset all PCM and DMAs in case of stop/prepare xrun
sequences.

Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/pcm.c       | 11 +++++++++++
 sound/soc/sof/sof-audio.c |  1 +
 sound/soc/sof/sof-audio.h |  1 +
 3 files changed, 13 insertions(+)
diff mbox series

Patch

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index ed09756f6af6..fbd7e045bcfb 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -276,6 +276,8 @@  static int sof_pcm_trigger(struct snd_soc_component *component,
 	dev_dbg(component->dev, "pcm: trigger stream %d dir %d cmd %d\n",
 		spcm->pcm.pcm_id, substream->stream, cmd);
 
+	spcm->pending_stop[substream->stream] = false;
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		ipc_first = true;
@@ -345,6 +347,15 @@  static int sof_pcm_trigger(struct snd_soc_component *component,
 		/* invoke platform trigger to stop DMA even if pcm_ops isn't set or if it failed */
 		if (!pcm_ops || !pcm_ops->platform_stop_during_hw_free)
 			snd_sof_pcm_platform_trigger(sdev, substream, cmd);
+
+		/*
+		 * set the pending_stop flag to indicate that pipeline stop has been delayed.
+		 * This will be used later to stop the pipelines during prepare when recovering
+		 * from xruns.
+		 */
+		if (pcm_ops && pcm_ops->platform_stop_during_hw_free &&
+		    cmd == SNDRV_PCM_TRIGGER_STOP)
+			spcm->pending_stop[substream->stream] = true;
 		break;
 	default:
 		break;
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index b5ca2861edbd..32fef64ef10d 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -852,6 +852,7 @@  int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *subs
 		}
 
 		spcm->prepared[substream->stream] = false;
+		spcm->pending_stop[substream->stream] = false;
 	}
 
 	/* reset the DMA */
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 7c08f915b35b..f4134257789e 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -349,6 +349,7 @@  struct snd_sof_pcm {
 	struct list_head list;	/* list in sdev pcm list */
 	struct snd_pcm_hw_params params[2];
 	bool prepared[2]; /* PCM_PARAMS set successfully */
+	bool pending_stop[2]; /* only used if (!pcm_ops->platform_stop_during_hw_free) */
 };
 
 struct snd_sof_led_control {