summaryrefslogtreecommitdiff
path: root/sound/soc/sof/sof-audio.c
diff options
context:
space:
mode:
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>2021-09-27 15:05:17 +0300
committerMark Brown <broonie@kernel.org>2021-10-01 22:48:31 +0300
commitc0e7969cf9c4fd347b33a8056960e8448f6b51c0 (patch)
tree93ae778bcb54b77be30a95e64a6f1a9faa200f78 /sound/soc/sof/sof-audio.c
parent5fcdbb2d45df6afb654674379546996b0027aa3e (diff)
downloadlinux-c0e7969cf9c4fd347b33a8056960e8448f6b51c0.tar.xz
ASoC: SOF: topology: Add kernel parameter for topology verification
Add a kernel debug flag to enable a one-shot topology verification for all pipelines including the dynamic ones. If the debug flag is set, all the topology component loading will be verified during the complete callback. 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> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20210927120517.20505-13-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/sof-audio.c')
-rw-r--r--sound/soc/sof/sof-audio.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index 7b4dd64576fa..c4cabe26b157 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -589,7 +589,7 @@ const struct sof_ipc_pipe_new *snd_sof_pipeline_find(struct snd_sof_dev *sdev,
return NULL;
}
-int sof_set_up_pipelines(struct device *dev)
+int sof_set_up_pipelines(struct device *dev, bool verify)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_sof_widget *swidget;
@@ -599,7 +599,7 @@ int sof_set_up_pipelines(struct device *dev)
/* restore pipeline components */
list_for_each_entry_reverse(swidget, &sdev->widget_list, list) {
/* only set up the widgets belonging to static pipelines */
- if (swidget->dynamic_pipeline_widget)
+ if (!verify && swidget->dynamic_pipeline_widget)
continue;
/* update DAI config. The IPC will be sent in sof_widget_setup() */
@@ -630,8 +630,8 @@ int sof_set_up_pipelines(struct device *dev)
list_for_each_entry(sroute, &sdev->route_list, list) {
/* only set up routes belonging to static pipelines */
- if (sroute->src_widget->dynamic_pipeline_widget ||
- sroute->sink_widget->dynamic_pipeline_widget)
+ if (!verify && (sroute->src_widget->dynamic_pipeline_widget ||
+ sroute->sink_widget->dynamic_pipeline_widget))
continue;
ret = sof_route_setup_ipc(sdev, sroute);
@@ -646,7 +646,7 @@ int sof_set_up_pipelines(struct device *dev)
switch (swidget->id) {
case snd_soc_dapm_scheduler:
/* only complete static pipelines */
- if (swidget->dynamic_pipeline_widget)
+ if (!verify && swidget->dynamic_pipeline_widget)
continue;
swidget->complete =
@@ -661,24 +661,37 @@ int sof_set_up_pipelines(struct device *dev)
}
/*
- * This function doesn't free widgets. It only resets the set up status for all routes and
- * use_count for all widgets.
+ * This function doesn't free widgets during suspend. It only resets the set up status for all
+ * routes and use_count for all widgets.
*/
-void sof_tear_down_pipelines(struct device *dev)
+int sof_tear_down_pipelines(struct device *dev, bool verify)
{
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_sof_widget *swidget;
struct snd_sof_route *sroute;
+ int ret;
/*
- * No need to protect swidget->use_count and sroute->setup as this function is called only
- * during the suspend callback and all streams should be suspended by then
+ * 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.
*/
- list_for_each_entry(swidget, &sdev->widget_list, list)
- swidget->use_count = 0;
+ list_for_each_entry_reverse(swidget, &sdev->widget_list, list) {
+ if (!verify) {
+ swidget->use_count = 0;
+ continue;
+ }
+
+ ret = sof_widget_free(sdev, swidget);
+ if (ret < 0)
+ return ret;
+ }
list_for_each_entry(sroute, &sdev->route_list, list)
sroute->setup = false;
+
+ return 0;
}
/*