ASoC: SOF: sof-audio: setup sched widgets during pipeline complete step
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tue, 23 Nov 2021 17:16:04 +0000 (19:16 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 11:03:04 +0000 (12:03 +0100)
commit 01429183f479c54c1b5d15453a8ce574ea43e525 upstream.

Older firmware prior to ABI 3.19 has a dependency where the scheduler
widgets need to be setup last. Moving the call to sof_widget_setup()
before the pipeline_complete() call also helps remove the need for the
'reverse' direction when walking through the widget list - this was
only working because of the topology macros but the topology does not
require any order.

Fixes: 5fcdbb2d45df ("ASoC: SOF: Add support for dynamic pipelines")
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20211123171606.129350-1-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
sound/soc/sof/sof-audio.c

index 669d5c924f6bf743e9bd86ab7983b2ace661bd44..a4c9806d294e3f9350fe17ee05bf2cb8e446db45 100644 (file)
@@ -596,16 +596,25 @@ const struct sof_ipc_pipe_new *snd_sof_pipeline_find(struct snd_sof_dev *sdev,
 
 int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify)
 {
+       struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
        struct snd_sof_widget *swidget;
        struct snd_sof_route *sroute;
        int ret;
 
        /* restore pipeline components */
-       list_for_each_entry_reverse(swidget, &sdev->widget_list, list) {
+       list_for_each_entry(swidget, &sdev->widget_list, list) {
                /* only set up the widgets belonging to static pipelines */
                if (!verify && swidget->dynamic_pipeline_widget)
                        continue;
 
+               /*
+                * For older firmware, skip scheduler widgets in this loop,
+                * sof_widget_setup() will be called in the 'complete pipeline' loop
+                */
+               if (v->abi_version < SOF_ABI_VER(3, 19, 0) &&
+                   swidget->id == snd_soc_dapm_scheduler)
+                       continue;
+
                /* update DAI config. The IPC will be sent in sof_widget_setup() */
                if (WIDGET_IS_DAI(swidget->id)) {
                        struct snd_sof_dai *dai = swidget->private;
@@ -653,6 +662,12 @@ int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify)
                        if (!verify && swidget->dynamic_pipeline_widget)
                                continue;
 
+                       if (v->abi_version < SOF_ABI_VER(3, 19, 0)) {
+                               ret = sof_widget_setup(sdev, swidget);
+                               if (ret < 0)
+                                       return ret;
+                       }
+
                        swidget->complete =
                                snd_sof_complete_pipeline(sdev, swidget);
                        break;
@@ -681,7 +696,7 @@ int sof_tear_down_pipelines(struct snd_sof_dev *sdev, bool verify)
         * sroute->setup because during suspend all streams are suspended and during topology
         * loading the sound card unavailable to open PCMs.
         */
-       list_for_each_entry_reverse(swidget, &sdev->widget_list, list) {
+       list_for_each_entry(swidget, &sdev->widget_list, list) {
                if (swidget->dynamic_pipeline_widget)
                        continue;