diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index 893296f3fe395e..0b48fdf1b8e5b3 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -109,6 +109,8 @@ static int sdw_drv_probe(struct device *dev) ret = drv->probe(slave, id); if (ret) { + slave->ops = NULL; + name = drv->name; if (!name) name = drv->driver.name; @@ -152,6 +154,9 @@ static int sdw_drv_remove(struct device *dev) struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); int ret = 0; + slave->ops = NULL; + slave->probed = false; + if (drv->remove) ret = drv->remove(slave); @@ -165,6 +170,9 @@ static void sdw_drv_shutdown(struct device *dev) struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); + slave->ops = NULL; + slave->probed = false; + if (drv->shutdown) drv->shutdown(slave); } diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 30b46d20ceeb7f..d5e3564ec9f856 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -1065,6 +1065,46 @@ static int sof_connect_dai_widget(struct snd_soc_component *scomp, return 0; } +static void sof_disconnect_dai_widget(struct snd_soc_component *scomp, + struct snd_soc_dapm_widget *w) +{ + struct snd_soc_card *card = scomp->card; + struct snd_soc_pcm_runtime *rtd; + struct snd_soc_dai *cpu_dai; + int i; + + list_for_each_entry(rtd, &card->rtd_list, list) { + + if (!w->sname || !rtd->dai_link->stream_name) + continue; + + /* does stream match DAI link ? */ + if (strcmp(w->sname, rtd->dai_link->stream_name)) + continue; + + switch (w->id) { + case snd_soc_dapm_dai_out: + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { + if (cpu_dai->capture_widget == w) { + cpu_dai->capture_widget = NULL; + break; + } + } + break; + case snd_soc_dapm_dai_in: + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { + if (cpu_dai->playback_widget == w) { + cpu_dai->playback_widget = NULL; + break; + } + } + break; + default: + break; + } + } +} + /* bind PCM ID to host component ID */ static int spcm_bind(struct snd_soc_component *scomp, struct snd_sof_pcm *spcm, int dir) @@ -1383,6 +1423,9 @@ static int sof_widget_unload(struct snd_soc_component *scomp, if (dai) list_del(&dai->list); + + sof_disconnect_dai_widget(scomp, widget); + break; default: break;