return 0;
 }
 
-/*
- * For older firmware, this function doesn't free widgets for static pipelines during suspend.
- * It only resets use_count for all widgets.
- */
-static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify)
+static int sof_ipc3_free_widgets_in_list(struct snd_sof_dev *sdev, bool include_scheduler,
+                                        bool *dyn_widgets, bool verify)
 {
        struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
        struct snd_sof_widget *swidget;
-       struct snd_sof_route *sroute;
-       bool dyn_widgets = false;
        int ret;
 
-       /*
-        * 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 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) {
-                       dyn_widgets = true;
+                       *dyn_widgets = true;
                        continue;
                }
 
                        continue;
                }
 
+               if (include_scheduler && swidget->id != snd_soc_dapm_scheduler)
+                       continue;
+
+               if (!include_scheduler && swidget->id == snd_soc_dapm_scheduler)
+                       continue;
+
                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.
+ */
+static int sof_ipc3_tear_down_all_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;
+       bool dyn_widgets = false;
+       int ret;
+
+       /*
+        * 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 running streams are suspended and during
+        * topology loading the sound card unavailable to open PCMs. Do not free the scheduler
+        * widgets yet so that the secondary cores do not get powered down before all the widgets
+        * associated with the scheduler are freed.
+        */
+       ret = sof_ipc3_free_widgets_in_list(sdev, false, &dyn_widgets, verify);
+       if (ret < 0)
+               return ret;
+
+       /* free all the scheduler widgets now */
+       ret = sof_ipc3_free_widgets_in_list(sdev, true, &dyn_widgets, verify);
+       if (ret < 0)
+               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.