@@ -208,6 +208,8 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
if (target_state == SOF_DSP_PM_D0)
goto suspend;
+ sof_tear_down_pipelines(dev);
+
/* release trace */
snd_sof_release_trace(sdev);
@@ -276,6 +276,7 @@ int sof_restore_pipelines(struct device *dev)
return ret;
}
+ sroute->setup = true;
}
/* restore dai links */
@@ -317,6 +318,20 @@ int sof_restore_pipelines(struct device *dev)
return ret;
}
+/* This function doesn't free widgets. It only resets the set up status for all routes */
+void sof_tear_down_pipelines(struct device *dev)
+{
+ struct snd_sof_dev *sdev = dev_get_drvdata(dev);
+ struct snd_sof_route *sroute;
+
+ /*
+ * No need to protect sroute->setup as this function is called only during the suspend
+ * callback and all streams should be suspended by then
+ */
+ list_for_each_entry(sroute, &sdev->route_list, list)
+ sroute->setup = false;
+}
+
/*
* Generic object lookup APIs.
*/
@@ -118,6 +118,9 @@ struct snd_sof_route {
struct snd_soc_dapm_route *route;
struct list_head list; /* list in sdev route list */
+ struct snd_sof_widget *src_widget;
+ struct snd_sof_widget *sink_widget;
+ bool setup;
void *private;
};
@@ -240,6 +243,7 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
/* PM */
int sof_restore_pipelines(struct device *dev);
+void sof_tear_down_pipelines(struct device *dev);
int sof_set_hw_params_upon_resume(struct device *dev);
bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev);
bool snd_sof_dsp_only_d0i3_compatible_stream_active(struct snd_sof_dev *sdev);
@@ -3501,6 +3501,9 @@ static int sof_route_load(struct snd_soc_component *scomp, int index,
sroute->route = route;
dobj->private = sroute;
sroute->private = connect;
+ sroute->src_widget = source_swidget;
+ sroute->sink_widget = sink_swidget;
+ sroute->setup = true;
/* add route to route list */
list_add(&sroute->list, &sdev->route_list);