IPC4 requires that the widgets be unbound in the firmware before they are freed. So add a new op in struct sof_ipc_tplg_ops that will be used to send the IPC to the firmware to unbind widgets. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@xxxxxxxxxxxxxxx> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> Reviewed-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@xxxxxxxxxxxxxxx> --- sound/soc/sof/sof-audio.c | 7 ++++++- sound/soc/sof/sof-audio.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 0bc6c3ef0cd4..07576ed3c4fa 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -14,11 +14,16 @@ static void sof_reset_route_setup_status(struct snd_sof_dev *sdev, struct snd_sof_widget *widget) { + const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; struct snd_sof_route *sroute; list_for_each_entry(sroute, &sdev->route_list, list) - if (sroute->src_widget == widget || sroute->sink_widget == widget) + if (sroute->src_widget == widget || sroute->sink_widget == widget) { + if (sroute->setup && tplg_ops->route_free) + tplg_ops->route_free(sdev, sroute); + sroute->setup = false; + } } int sof_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index e3cfc813975b..7ca87056b106 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -146,6 +146,7 @@ struct sof_ipc_tplg_widget_ops { * initialized to 0. * @control: Pointer to the IPC-specific ops for topology kcontrol IO * @route_setup: Function pointer for setting up pipeline connections + * @route_free: Optional op for freeing pipeline connections. * @token_list: List of all tokens supported by the IPC version. The size of the token_list * array should be SOF_TOKEN_COUNT. The unused elements in the array will be * initialized to 0. @@ -163,6 +164,7 @@ struct sof_ipc_tplg_ops { const struct sof_ipc_tplg_widget_ops *widget; const struct sof_ipc_tplg_control_ops *control; int (*route_setup)(struct snd_sof_dev *sdev, struct snd_sof_route *sroute); + int (*route_free)(struct snd_sof_dev *sdev, struct snd_sof_route *sroute); const struct sof_token_info *token_list; int (*control_setup)(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol); int (*control_free)(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol); -- 2.25.1