diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index b642835e14df6..bc8ca1e05b83d 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2126,7 +2126,6 @@ static int sof_complete(struct snd_soc_component *scomp) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg); - struct snd_sof_widget *swidget, *comp_swidget; const struct sof_ipc_tplg_widget_ops *widget_ops; struct snd_sof_control *scontrol; struct snd_sof_pipeline *spipe; @@ -2145,37 +2144,38 @@ static int sof_complete(struct snd_soc_component *scomp) } } - /* - * then update all widget IPC structures. If any of the ipc_setup callbacks fail, the - * topology will be removed and all widgets will be unloaded resulting in freeing all - * associated memories. - */ - list_for_each_entry(swidget, &sdev->widget_list, list) { - if (widget_ops && widget_ops[swidget->id].ipc_setup) { - ret = widget_ops[swidget->id].ipc_setup(swidget); + /* set up the IPC structures for the pipeline widgets */ + list_for_each_entry(spipe, &sdev->pipeline_list, list) { + struct snd_sof_widget *pipe_widget = spipe->pipe_widget; + struct snd_sof_widget *swidget; + + /* Update the scheduler widget's IPC structure */ + if (widget_ops && widget_ops[pipe_widget->id].ipc_setup) { + ret = widget_ops[pipe_widget->id].ipc_setup(pipe_widget); if (ret < 0) { dev_err(sdev->dev, "failed updating IPC struct for %s\n", - swidget->widget->name); + pipe_widget->widget->name); return ret; } } - } - /* set the pipe_widget and apply the dynamic_pipeline_widget_flag */ - list_for_each_entry(spipe, &sdev->pipeline_list, list) { - struct snd_sof_widget *pipe_widget = spipe->pipe_widget; - - /* - * Apply the dynamic_pipeline_widget flag and set the pipe_widget field - * for all widgets that have the same pipeline ID as the scheduler widget. - * Skip the scheduler widgets as they have their pipeline set during widget_ready - */ - list_for_each_entry(comp_swidget, &sdev->widget_list, list) - if (comp_swidget->widget->id != snd_soc_dapm_scheduler && - comp_swidget->pipeline_id == pipe_widget->pipeline_id) { - ret = sof_set_widget_pipeline(sdev, spipe, comp_swidget); + /* set the pipeline and update the IPC structure for the non scheduler widgets */ + list_for_each_entry(swidget, &sdev->widget_list, list) + if (swidget->widget->id != snd_soc_dapm_scheduler && + swidget->pipeline_id == pipe_widget->pipeline_id) { + ret = sof_set_widget_pipeline(sdev, spipe, swidget); if (ret < 0) return ret; + + if (widget_ops && widget_ops[swidget->id].ipc_setup) { + ret = widget_ops[swidget->id].ipc_setup(swidget); + if (ret < 0) { + dev_err(sdev->dev, + "failed updating IPC struct for %s\n", + swidget->widget->name); + return ret; + } + } } }