diff mbox series

[RFC,v2,1/4] ASoC: Intel: avs: Simplify pipeline management

Message ID 20241112114006.2812697-2-amadeuszx.slawinski@linux.intel.com (mailing list archive)
State RFC
Headers show
Series Add support for detection | expand

Commit Message

Amadeusz Sławiński Nov. 12, 2024, 11:40 a.m. UTC
DSP pipelines follow simple state machine scheme:
CREATE -> RESET -> PAUSE -> RUNNING -> PAUSE -> RESET -> DELETE

When code was first designed there was assumption that code doesn't
remember pipeline state, so it can for example send reset command twice
to pipeline. Final version of code however remembers pipeline state and
prevents such operations, which allows us to significantly reduce number
of operations on pipelines.

Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
---
 sound/soc/intel/avs/pcm.c | 41 +++++++++++----------------------------
 1 file changed, 11 insertions(+), 30 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 945f9c0a6a545..83eb01cf17e9c 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -206,11 +206,15 @@  static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
 static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
 	struct avs_dma_data *data;
+	int ret;
 
 	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
 
 	data = snd_soc_dai_get_dma_data(dai, substream);
 	if (data->path) {
+		ret = avs_path_reset(data->path);
+		if (ret < 0)
+			dev_err(dai->dev, "reset path failed: %d\n", ret);
 		avs_path_free(data->path);
 		data->path = NULL;
 	}
@@ -234,12 +238,6 @@  static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cm
 		fallthrough;
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		ret = avs_path_pause(data->path);
-		if (ret < 0) {
-			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
-			break;
-		}
-
 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 		if (ret < 0)
 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
@@ -254,10 +252,6 @@  static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cm
 		ret = avs_path_pause(data->path);
 		if (ret < 0)
 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
-
-		ret = avs_path_reset(data->path);
-		if (ret < 0)
-			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 		break;
 
 	default:
@@ -332,6 +326,7 @@  static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn
 	struct hdac_ext_stream *link_stream;
 	struct hdac_ext_link *link;
 	struct hda_codec *codec;
+	int ret;
 
 	dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
 
@@ -341,6 +336,9 @@  static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn
 
 	link_stream = data->link_stream;
 	link_stream->link_prepared = false;
+	ret = avs_path_reset(data->path);
+	if (ret < 0)
+		dev_err(dai->dev, "reset path failed: %d\n", ret);
 	avs_path_free(data->path);
 	data->path = NULL;
 
@@ -422,12 +420,6 @@  static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		snd_hdac_ext_stream_start(data->link_stream);
 
-		ret = avs_path_pause(data->path);
-		if (ret < 0) {
-			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
-			break;
-		}
-
 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 		if (ret < 0)
 			dev_err(dai->dev, "run BE path failed: %d\n", ret);
@@ -444,10 +436,6 @@  static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
 			dev_err(dai->dev, "pause BE path failed: %d\n", ret);
 
 		snd_hdac_ext_stream_clear(data->link_stream);
-
-		ret = avs_path_reset(data->path);
-		if (ret < 0)
-			dev_err(dai->dev, "reset BE path failed: %d\n", ret);
 		break;
 
 	default:
@@ -621,6 +609,9 @@  static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_
 	if (ret < 0)
 		dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
 
+	ret = avs_path_reset(data->path);
+	if (ret < 0)
+		dev_err(dai->dev, "reset path failed: %d\n", ret);
 	avs_path_free(data->path);
 	data->path = NULL;
 	snd_hdac_stream_cleanup(hdac_stream(host_stream));
@@ -782,12 +773,6 @@  static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru
 		if (cmd == SNDRV_PCM_TRIGGER_RESUME)
 			snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
 
-		ret = avs_path_pause(data->path);
-		if (ret < 0) {
-			dev_err(dai->dev, "pause FE path failed: %d\n", ret);
-			break;
-		}
-
 		ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
 		if (ret < 0)
 			dev_err(dai->dev, "run FE path failed: %d\n", ret);
@@ -807,10 +792,6 @@  static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru
 		spin_lock_irqsave(&bus->reg_lock, flags);
 		avs_hda_stream_stop(bus, host_stream);
 		spin_unlock_irqrestore(&bus->reg_lock, flags);
-
-		ret = avs_path_reset(data->path);
-		if (ret < 0)
-			dev_err(dai->dev, "reset FE path failed: %d\n", ret);
 		break;
 
 	default: