ASoC: SOF: topology: dynamically allocate and store DAI widget->private
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tue, 13 Feb 2024 10:12:41 +0000 (12:12 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 13 Feb 2024 13:28:58 +0000 (13:28 +0000)
For dspless mode, we need to allocate and store an 'sdai'
structure. The existing code allocate the data on the stack and does
not set the widget->private pointer.

This minor change should not have any impact on existing DAIs, even
when the DSP is used.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://msgid.link/r/20240213101247.28887-10-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/sof-audio.c
sound/soc/sof/topology.c

index 9163975c9c3fb905d0df5064879a1e3237d9155c..e693dcb475e4d6a28273d920b36b706c21df6dd9 100644 (file)
@@ -46,7 +46,6 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
 {
        const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
        struct snd_sof_pipeline *spipe = swidget->spipe;
-       struct snd_sof_widget *pipe_widget;
        int err = 0;
        int ret;
 
@@ -59,8 +58,6 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
        if (--swidget->use_count)
                return 0;
 
-       pipe_widget = swidget->spipe->pipe_widget;
-
        /* reset route setup status for all routes that contain this widget */
        sof_reset_route_setup_status(sdev, swidget);
 
@@ -109,8 +106,9 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
         * free the scheduler widget (same as pipe_widget) associated with the current swidget.
         * skip for static pipelines
         */
-       if (swidget->dynamic_pipeline_widget && swidget->id != snd_soc_dapm_scheduler) {
-               ret = sof_widget_free_unlocked(sdev, pipe_widget);
+       if (swidget->spipe && swidget->dynamic_pipeline_widget &&
+           swidget->id != snd_soc_dapm_scheduler) {
+               ret = sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget);
                if (ret < 0 && !err)
                        err = ret;
        }
index 25fb0d1443b6b6455efdf7e0ecf030f3555aee4b..915c2e88e32b400a6cc68469d44334c3ddf1e41c 100644 (file)
@@ -2356,23 +2356,29 @@ static int sof_dspless_widget_ready(struct snd_soc_component *scomp, int index,
        if (WIDGET_IS_DAI(w->id)) {
                struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
                struct snd_sof_widget *swidget;
-               struct snd_sof_dai dai;
+               struct snd_sof_dai *sdai;
                int ret;
 
                swidget = kzalloc(sizeof(*swidget), GFP_KERNEL);
                if (!swidget)
                        return -ENOMEM;
 
-               memset(&dai, 0, sizeof(dai));
+               sdai = kzalloc(sizeof(*sdai), GFP_KERNEL);
+               if (!sdai) {
+                       kfree(swidget);
+                       return -ENOMEM;
+               }
 
-               ret = sof_connect_dai_widget(scomp, w, tw, &dai);
+               ret = sof_connect_dai_widget(scomp, w, tw, sdai);
                if (ret) {
                        kfree(swidget);
+                       kfree(sdai);
                        return ret;
                }
 
                swidget->scomp = scomp;
                swidget->widget = w;
+               swidget->private = sdai;
                mutex_init(&swidget->setup_mutex);
                w->dobj.private = swidget;
                list_add(&swidget->list, &sdev->widget_list);
@@ -2396,6 +2402,7 @@ static int sof_dspless_widget_unload(struct snd_soc_component *scomp,
 
                /* remove and free swidget object */
                list_del(&swidget->list);
+               kfree(swidget->private);
                kfree(swidget);
        }