--- /dev/null
+From b2ebcf42a48f4560862bb811f3268767d17ebdcd Mon Sep 17 00:00:00 2001
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Date: Fri, 19 Nov 2021 21:26:18 +0200
+Subject: ASoC: SOF: free widgets in sof_tear_down_pipelines() for static pipelines
+
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+
+commit b2ebcf42a48f4560862bb811f3268767d17ebdcd upstream.
+
+Free widgets for static pipelines in sof_tear_down_pipelines().
+But this feature is unavailable in older firmware with ABI < 3.19.
+Just reset widget use_count's for this case. This would ensure that
+the secondary cores enabled required for topology setup are powered
+down properly before the primary core is powered off during
+system suspend.
+
+Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Link: https://lore.kernel.org/r/20211119192621.4096077-8-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 | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/sof/sof-audio.c
++++ b/sound/soc/sof/sof-audio.c
+@@ -665,11 +665,12 @@ int sof_set_up_pipelines(struct snd_sof_
+ }
+
+ /*
+- * This function doesn't free widgets during suspend. It only resets the set up status for all
+- * routes and use_count for all widgets.
++ * For older firmware, this function doesn't free widgets for static pipelines during suspend.
++ * It only resets use_count for all widgets.
+ */
+ int sof_tear_down_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;
+@@ -681,8 +682,14 @@ int sof_tear_down_pipelines(struct snd_s
+ * loading the sound card unavailable to open PCMs.
+ */
+ list_for_each_entry_reverse(swidget, &sdev->widget_list, list) {
+- if (!verify) {
++ if (swidget->dynamic_pipeline_widget)
++ continue;
++
++ /* Do not free widgets for static pipelines with FW ABI older than 3.19 */
++ if (!verify && !swidget->dynamic_pipeline_widget &&
++ v->abi_version < SOF_ABI_VER(3, 19, 0)) {
+ swidget->use_count = 0;
++ swidget->complete = 0;
+ continue;
+ }
+
--- /dev/null
+From 96da174024b9c63bd5d3358668d0bc12677be877 Mon Sep 17 00:00:00 2001
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Date: Tue, 23 Nov 2021 19:16:06 +0200
+Subject: ASoC: SOF: handle paused streams during system suspend
+
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+
+commit 96da174024b9c63bd5d3358668d0bc12677be877 upstream.
+
+During system suspend, paused streams do not get suspended.
+Therefore, we need to explicitly free these PCMs in the DSP
+and free the associated DAPM widgets so that they can be set
+up again during resume.
+
+Fixes: 5fcdbb2d45df ("ASoC: SOF: Add support for dynamic pipelines")
+Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Paul Olaru <paul.olaru@oss.nxp.com>
+Reviewed-by: Bard Liao <bard.liao@intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Link: https://lore.kernel.org/r/20211123171606.129350-3-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/pcm.c | 5 +--
+ sound/soc/sof/sof-audio.c | 74 ++++++++++++++++++++++++++++++++++++++++++++--
+ sound/soc/sof/sof-audio.h | 2 +
+ 3 files changed, 76 insertions(+), 5 deletions(-)
+
+--- a/sound/soc/sof/pcm.c
++++ b/sound/soc/sof/pcm.c
+@@ -100,9 +100,8 @@ void snd_sof_pcm_period_elapsed(struct s
+ }
+ EXPORT_SYMBOL(snd_sof_pcm_period_elapsed);
+
+-static int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream,
+- struct snd_sof_dev *sdev,
+- struct snd_sof_pcm *spcm)
++int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev,
++ struct snd_sof_pcm *spcm)
+ {
+ struct sof_ipc_stream stream;
+ struct sof_ipc_reply reply;
+--- a/sound/soc/sof/sof-audio.c
++++ b/sound/soc/sof/sof-audio.c
+@@ -122,6 +122,14 @@ int sof_widget_free(struct snd_sof_dev *
+ case snd_soc_dapm_buffer:
+ ipc_free.hdr.cmd |= SOF_IPC_TPLG_BUFFER_FREE;
+ break;
++ case snd_soc_dapm_dai_in:
++ case snd_soc_dapm_dai_out:
++ {
++ struct snd_sof_dai *dai = swidget->private;
++
++ dai->configured = false;
++ fallthrough;
++ }
+ default:
+ ipc_free.hdr.cmd |= SOF_IPC_TPLG_COMP_FREE;
+ break;
+@@ -680,6 +688,55 @@ int sof_set_up_pipelines(struct snd_sof_
+ }
+
+ /*
++ * Free the PCM, its associated widgets and set the prepared flag to false for all PCMs that
++ * did not get suspended(ex: paused streams) so the widgets can be set up again during resume.
++ */
++static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev)
++{
++ struct snd_sof_widget *swidget;
++ struct snd_sof_pcm *spcm;
++ int dir, ret;
++
++ /*
++ * free all PCMs and their associated DAPM widgets if their connected DAPM widget
++ * list is not NULL. This should only be true for paused streams at this point.
++ * This is equivalent to the handling of FE DAI suspend trigger for running streams.
++ */
++ list_for_each_entry(spcm, &sdev->pcm_list, list)
++ for_each_pcm_streams(dir) {
++ struct snd_pcm_substream *substream = spcm->stream[dir].substream;
++
++ if (!substream || !substream->runtime)
++ continue;
++
++ if (spcm->stream[dir].list) {
++ ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
++ if (ret < 0)
++ return ret;
++
++ ret = sof_widget_list_free(sdev, spcm, dir);
++ if (ret < 0) {
++ dev_err(sdev->dev, "failed to free widgets during suspend\n");
++ return ret;
++ }
++ }
++ }
++
++ /*
++ * free any left over DAI widgets. This is equivalent to the handling of suspend trigger
++ * for the BE DAI for running streams.
++ */
++ list_for_each_entry(swidget, &sdev->widget_list, list)
++ if (WIDGET_IS_DAI(swidget->id) && swidget->use_count == 1) {
++ ret = sof_widget_free(sdev, swidget);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
++/*
+ * For older firmware, this function doesn't free widgets for static pipelines during suspend.
+ * It only resets use_count for all widgets.
+ */
+@@ -693,8 +750,8 @@ int sof_tear_down_pipelines(struct snd_s
+ /*
+ * This function is called during suspend and for one-time topology verification during
+ * first boot. In both cases, there is no need to protect swidget->use_count and
+- * sroute->setup because during suspend all streams are suspended and during topology
+- * loading the sound card unavailable to open PCMs.
++ * sroute->setup because during suspend all running streams are suspended and during
++ * topology loading the sound card unavailable to open PCMs.
+ */
+ list_for_each_entry(swidget, &sdev->widget_list, list) {
+ if (swidget->dynamic_pipeline_widget)
+@@ -713,6 +770,19 @@ int sof_tear_down_pipelines(struct snd_s
+ return ret;
+ }
+
++ /*
++ * Tear down all pipelines associated with PCMs that did not get suspended
++ * and unset the prepare flag so that they can be set up again during resume.
++ * Skip this step for older firmware.
++ */
++ if (!verify && v->abi_version >= SOF_ABI_VER(3, 19, 0)) {
++ ret = sof_tear_down_left_over_pipelines(sdev);
++ if (ret < 0) {
++ dev_err(sdev->dev, "failed to tear down paused pipelines\n");
++ return ret;
++ }
++ }
++
+ list_for_each_entry(sroute, &sdev->route_list, list)
+ sroute->setup = false;
+
+--- a/sound/soc/sof/sof-audio.h
++++ b/sound/soc/sof/sof-audio.h
+@@ -267,4 +267,6 @@ int sof_widget_free(struct snd_sof_dev *
+ /* PCM */
+ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int dir);
+ int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int dir);
++int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev,
++ struct snd_sof_pcm *spcm);
+ #endif
--- /dev/null
+From 01429183f479c54c1b5d15453a8ce574ea43e525 Mon Sep 17 00:00:00 2001
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Date: Tue, 23 Nov 2021 19:16:04 +0200
+Subject: ASoC: SOF: sof-audio: setup sched widgets during pipeline complete step
+
+From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+
+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 | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/sof/sof-audio.c
++++ b/sound/soc/sof/sof-audio.c
+@@ -596,16 +596,25 @@ const struct sof_ipc_pipe_new *snd_sof_p
+
+ 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_
+ 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_s
+ * 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;
+
--- /dev/null
+From 7cc7b9ba21d4978d19f0e3edc2b00d44c9d66ff6 Mon Sep 17 00:00:00 2001
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Date: Fri, 19 Nov 2021 21:26:17 +0200
+Subject: ASoC: SOF: topology: remove sof_load_pipeline_ipc()
+
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+
+commit 7cc7b9ba21d4978d19f0e3edc2b00d44c9d66ff6 upstream.
+
+Remove the function sof_load_pipeline_ipc() and directly
+send the IPC instead. The pipeline core is already enabled
+with the call to sof_pipeline_core_enable() in sof_widget_setup().
+
+Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Link: https://lore.kernel.org/r/20211119192621.4096077-7-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 | 3 ++-
+ sound/soc/sof/sof-audio.h | 4 ----
+ sound/soc/sof/topology.c | 17 -----------------
+ 3 files changed, 2 insertions(+), 22 deletions(-)
+
+--- a/sound/soc/sof/sof-audio.c
++++ b/sound/soc/sof/sof-audio.c
+@@ -203,7 +203,8 @@ int sof_widget_setup(struct snd_sof_dev
+ break;
+ case snd_soc_dapm_scheduler:
+ pipeline = swidget->private;
+- ret = sof_load_pipeline_ipc(sdev, pipeline, &r);
++ ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline,
++ sizeof(*pipeline), &r, sizeof(r));
+ break;
+ default:
+ hdr = swidget->private;
+--- a/sound/soc/sof/sof-audio.h
++++ b/sound/soc/sof/sof-audio.h
+@@ -184,10 +184,6 @@ void snd_sof_control_notify(struct snd_s
+ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file);
+ int snd_sof_complete_pipeline(struct snd_sof_dev *sdev,
+ struct snd_sof_widget *swidget);
+-
+-int sof_load_pipeline_ipc(struct snd_sof_dev *sdev,
+- struct sof_ipc_pipe_new *pipeline,
+- struct sof_ipc_comp_reply *r);
+ int sof_pipeline_core_enable(struct snd_sof_dev *sdev,
+ const struct snd_sof_widget *swidget);
+
+--- a/sound/soc/sof/topology.c
++++ b/sound/soc/sof/topology.c
+@@ -1690,23 +1690,6 @@ err:
+ /*
+ * Pipeline Topology
+ */
+-int sof_load_pipeline_ipc(struct snd_sof_dev *sdev,
+- struct sof_ipc_pipe_new *pipeline,
+- struct sof_ipc_comp_reply *r)
+-{
+- int ret = sof_core_enable(sdev, pipeline->core);
+-
+- if (ret < 0)
+- return ret;
+-
+- ret = sof_ipc_tx_message(sdev->ipc, pipeline->hdr.cmd, pipeline,
+- sizeof(*pipeline), r, sizeof(*r));
+- if (ret < 0)
+- dev_err(sdev->dev, "error: load pipeline ipc failure\n");
+-
+- return ret;
+-}
+-
+ static int sof_widget_load_pipeline(struct snd_soc_component *scomp, int index,
+ struct snd_sof_widget *swidget,
+ struct snd_soc_tplg_dapm_widget *tw)
kvm-x86-partially-allow-kvm_set_cpuid-2-after-kvm_run.patch
kvm-selftests-rename-get_cpuid_test-to-cpuid_test.patch
kvm-selftests-test-kvm_set_cpuid2-after-kvm_run.patch
+asoc-sof-topology-remove-sof_load_pipeline_ipc.patch
+asoc-sof-free-widgets-in-sof_tear_down_pipelines-for-static-pipelines.patch
+asoc-sof-sof-audio-setup-sched-widgets-during-pipeline-complete-step.patch
+asoc-sof-handle-paused-streams-during-system-suspend.patch