Blob Blame History Raw
From dc4fc0ae94cf87f1017f158b6fa2b7536ef29b4e Mon Sep 17 00:00:00 2001
From: Libin Yang <libin.yang@intel.com>
Date: Fri, 8 Jul 2022 15:05:16 -0500
Subject: [PATCH] ASoC: SOF: ipc4-topology: free memories allocated in sof_ipc4_get_audio_fmt
Mime-version: 1.0
Content-type: text/plain; charset=UTF-8
Content-transfer-encoding: 8bit
Git-commit: dc4fc0ae94cf87f1017f158b6fa2b7536ef29b4e
Patch-mainline: v6.0-rc1
References: jsc#PED-850

Free the memories allocated in sof_ipc4_get_audio_fmt in error handling
and ipc_free()

Fixes: 2cabd02b6090 ("ASoC: SOF: ipc4-topology: Add support for parsing AIF_IN/AIF_OUT widgets")
Fixes: abfb536bd116 ("ASoC: SOF: ipc4-topology: Add support for parsing DAI_IN/DAI_OUT widgets")
Fixes: 4f838ab20812 ("ASoC: SOF: ipc4-topology: Add support for parsing and preparing pga widgets")
Fixes: 4d4ba014ac4b ("ASoC: SOF: ipc4-topology: Add support for parsing mixer widgets")
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Libin Yang <libin.yang@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220708200516.26853-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 sound/soc/sof/ipc4-topology.c | 48 ++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 2d157ea79db5..22ea628d78d0 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -263,6 +263,16 @@ static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp,
 	return ret;
 }
 
+/* release the memory allocated in sof_ipc4_get_audio_fmt */
+static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt)
+
+{
+	kfree(available_fmt->base_config);
+	available_fmt->base_config = NULL;
+	kfree(available_fmt->out_audio_fmt);
+	available_fmt->out_audio_fmt = NULL;
+}
+
 static void sof_ipc4_widget_free_comp(struct snd_sof_widget *swidget)
 {
 	kfree(swidget->private);
@@ -341,7 +351,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
 						 GFP_KERNEL);
 	if (!available_fmt->dma_buffer_size) {
 		ret = -ENOMEM;
-		goto free_copier;
+		goto free_available_fmt;
 	}
 
 	ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size,
@@ -392,6 +402,8 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
 	kfree(ipc4_copier->gtw_attr);
 err:
 	kfree(available_fmt->dma_buffer_size);
+free_available_fmt:
+	sof_ipc4_free_audio_fmt(available_fmt);
 free_copier:
 	kfree(ipc4_copier);
 	swidget->private = NULL;
@@ -440,7 +452,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
 						 GFP_KERNEL);
 	if (!available_fmt->dma_buffer_size) {
 		ret = -ENOMEM;
-		goto free_copier;
+		goto free_available_fmt;
 	}
 
 	ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size,
@@ -540,6 +552,8 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget)
 	kfree(ipc4_copier->copier_config);
 err:
 	kfree(available_fmt->dma_buffer_size);
+free_available_fmt:
+	sof_ipc4_free_audio_fmt(available_fmt);
 free_copier:
 	kfree(ipc4_copier);
 	dai->private = NULL;
@@ -677,11 +691,24 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
 
 	return 0;
 err:
+	sof_ipc4_free_audio_fmt(&gain->available_fmt);
 	kfree(gain);
 	swidget->private = NULL;
 	return ret;
 }
 
+static void sof_ipc4_widget_free_comp_pga(struct snd_sof_widget *swidget)
+{
+	struct sof_ipc4_gain *gain = swidget->private;
+
+	if (!gain)
+		return;
+
+	sof_ipc4_free_audio_fmt(&gain->available_fmt);
+	kfree(swidget->private);
+	swidget->private = NULL;
+}
+
 static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
 {
 	struct snd_soc_component *scomp = swidget->scomp;
@@ -707,11 +734,24 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
 
 	return 0;
 err:
+	sof_ipc4_free_audio_fmt(&mixer->available_fmt);
 	kfree(mixer);
 	swidget->private = NULL;
 	return ret;
 }
 
+static void sof_ipc4_widget_free_comp_mixer(struct snd_sof_widget *swidget)
+{
+	struct sof_ipc4_mixer *mixer = swidget->private;
+
+	if (!mixer)
+		return;
+
+	sof_ipc4_free_audio_fmt(&mixer->available_fmt);
+	kfree(swidget->private);
+	swidget->private = NULL;
+}
+
 static void
 sof_ipc4_update_pipeline_mem_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget,
 				   struct sof_ipc4_base_module_cfg *base_config)
@@ -1746,11 +1786,11 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY
 	[snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, sof_ipc4_widget_free_comp,
 				    pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL,
 				    NULL, NULL},
-	[snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp,
+	[snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp_pga,
 			      pga_token_list, ARRAY_SIZE(pga_token_list), NULL,
 			      sof_ipc4_prepare_gain_module,
 			      sof_ipc4_unprepare_generic_module},
-	[snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp,
+	[snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp_mixer,
 				mixer_token_list, ARRAY_SIZE(mixer_token_list),
 				NULL, sof_ipc4_prepare_mixer_module,
 				sof_ipc4_unprepare_generic_module},
-- 
2.35.3