diff mbox series

[12/17] ASoC: SOF: Intel: hda: Clear Soundwire node ID during BE DAI hw_free

Message ID 20240402151828.175002-13-pierre-louis.bossart@linux.intel.com (mailing list archive)
State Accepted
Commit bfe9225455c032c9dd5637047760cf59562e599f
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
From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

When an xrun happens, the BE DAI hw_params doesn't get invoked before
the stream restarts with a prepare. In this case, clearing the node ID
when the DAI widget is freed and unprepared will result in an error when
it is re-initialized. In order to avoid this, move the code to clear the
node ID to the BE DAI hw_free op to keep it balanced with the BE DAI
hw_params.

Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@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/intel/hda.c     | 24 ++++++++++++++++++++++++
 sound/soc/sof/ipc4-topology.c |  4 ----
 2 files changed, 24 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index ae1a38f20bdb..2c64c25d6f3b 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -31,6 +31,7 @@ 
 #include "../sof-audio.h"
 #include "../sof-pci-dev.h"
 #include "../ops.h"
+#include "../ipc4-topology.h"
 #include "hda.h"
 #include "telemetry.h"
 
@@ -150,8 +151,31 @@  static int sdw_params_stream(struct device *dev,
 	return hda_dai_config(w, SOF_DAI_CONFIG_FLAGS_HW_PARAMS, &data);
 }
 
+static int sdw_params_free(struct device *dev, struct sdw_intel_stream_free_data *free_data)
+{
+	struct snd_soc_dai *d = free_data->dai;
+	struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(d, free_data->substream->stream);
+	struct snd_sof_dev *sdev = widget_to_sdev(w);
+
+	if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
+		struct snd_sof_widget *swidget = w->dobj.private;
+		struct snd_sof_dai *dai = swidget->private;
+		struct sof_ipc4_copier_data *copier_data;
+		struct sof_ipc4_copier *ipc4_copier;
+
+		ipc4_copier = dai->private;
+		copier_data = &ipc4_copier->data;
+
+		/* clear the node ID */
+		copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
+	}
+
+	return 0;
+}
+
 struct sdw_intel_ops sdw_callback = {
 	.params_stream = sdw_params_stream,
+	.free_stream = sdw_params_free,
 };
 
 static int sdw_ace2x_params_stream(struct device *dev,
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 6b9b16f3157e..e0e4f356275f 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -1296,7 +1296,6 @@  static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
 		}
 
 		if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) {
-			struct sof_ipc4_copier_data *copier_data = &ipc4_copier->data;
 			struct sof_ipc4_alh_configuration_blob *blob;
 			unsigned int group_id;
 
@@ -1306,9 +1305,6 @@  static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
 					   ALH_MULTI_GTW_BASE;
 				ida_free(&alh_group_ida, group_id);
 			}
-
-			/* clear the node ID */
-			copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK;
 		}
 	}