| From f540f4328800b784a8d74e0a14faa515f9880efe Mon Sep 17 00:00:00 2001 |
| From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> |
| Date: Thu, 4 Apr 2019 17:30:40 -0700 |
| Subject: ASoC: core: remove link components before cleaning up card resources |
| |
| [ Upstream commit f96fb7d198ca624fe33c4145a004eb5a3d0eddec ] |
| |
| When the card is registered by the machine driver, |
| dai link components are probed after the snd_card is |
| created. This is done in snd_soc_bind_card() which calls |
| snd_soc_instantiate_card() to first create the snd_card |
| and then probes the link components by calling |
| soc_probe_link_components(). The snd_card is used by the |
| component driver to add the kcontrols associated |
| with dapm widgets to the card. |
| |
| When the machine driver is unregistered, the snd_card |
| is freed when the card resources are cleaned up. |
| But the snd_card needs to be valid while unloading the |
| topology dapm widgets in order to remove the kcontrols |
| from the card. |
| |
| Since, unloading topology is done when the component |
| driver is removed, the link components should be removed |
| in snd_soc_unbind_card(). This will ensure that the kcontrols |
| are removed before the card resources are cleaned up and |
| the snd_card itself is freed. |
| |
| Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/soc/soc-core.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c |
| index 46e3ab0fced47..fe99b02bbf171 100644 |
| --- a/sound/soc/soc-core.c |
| +++ b/sound/soc/soc-core.c |
| @@ -2828,10 +2828,21 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card); |
| |
| static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister) |
| { |
| + struct snd_soc_pcm_runtime *rtd; |
| + int order; |
| + |
| if (card->instantiated) { |
| card->instantiated = false; |
| snd_soc_dapm_shutdown(card); |
| snd_soc_flush_all_delayed_work(card); |
| + |
| + /* remove all components used by DAI links on this card */ |
| + for_each_comp_order(order) { |
| + for_each_card_rtds(card, rtd) { |
| + soc_remove_link_components(card, rtd, order); |
| + } |
| + } |
| + |
| soc_cleanup_card_resources(card); |
| if (!unregister) |
| list_add(&card->list, &unbind_card_list); |
| -- |
| 2.20.1 |
| |