summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBard liao <yung-chuan.liao@linux.intel.com>2019-02-01 20:07:40 +0300
committerMark Brown <broonie@kernel.org>2019-02-04 13:59:30 +0300
commitadfebb51e1750c5df9e5d42f505b73c5542a879d (patch)
tree98e210fd99a663651b2ecbd7ca4a0753f0e32c1a
parent78a24e10cd94420f1b4e2dc5923ae7109e2aaba1 (diff)
downloadlinux-adfebb51e1750c5df9e5d42f505b73c5542a879d.tar.xz
ASoC: topology: unload physical dai link in remove
soc_tplg_link_config() will find the physical dai link and call soc_tplg_dai_link_load() to load the BE dai link. Currently remove_link() is only used to remove the FE dai link which is created by the topology. The BE dai link cannot however be unloaded in snd_soc_tplg_component _remove(), which is problematic if anything needs to be released or reinitialized. This patch aligns the definitions of dynamic types with the existing UAPI and adds a new remove_backend_link() routine to unload the the BE dai link when snd_soc_tplg_component_remove() is invoked. Signed-off-by: Bard liao <yung-chuan.liao@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/soc-topology.h1
-rw-r--r--sound/soc/soc-topology.c32
2 files changed, 33 insertions, 0 deletions
diff --git a/include/sound/soc-topology.h b/include/sound/soc-topology.h
index 8c43cfc240fa..5223896de26f 100644
--- a/include/sound/soc-topology.h
+++ b/include/sound/soc-topology.h
@@ -45,6 +45,7 @@ enum snd_soc_dobj_type {
SND_SOC_DOBJ_DAI_LINK,
SND_SOC_DOBJ_PCM,
SND_SOC_DOBJ_CODEC_LINK,
+ SND_SOC_DOBJ_BACKEND_LINK,
};
/* dynamic control object */
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 23d421370e6c..246d2a2d43c8 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -557,6 +557,25 @@ static void remove_link(struct snd_soc_component *comp,
kfree(link);
}
+/* unload dai link */
+static void remove_backend_link(struct snd_soc_component *comp,
+ struct snd_soc_dobj *dobj, int pass)
+{
+ if (pass != SOC_TPLG_PASS_LINK)
+ return;
+
+ if (dobj->ops && dobj->ops->link_unload)
+ dobj->ops->link_unload(comp, dobj);
+
+ /*
+ * We don't free the link here as what remove_link() do since BE
+ * links are not allocated by topology.
+ * We however need to reset the dobj type to its initial values
+ */
+ dobj->type = SND_SOC_DOBJ_NONE;
+ list_del(&dobj->list);
+}
+
/* bind a kcontrol to it's IO handlers */
static int soc_tplg_kcontrol_bind_io(struct snd_soc_tplg_ctl_hdr *hdr,
struct snd_kcontrol_new *k,
@@ -2163,6 +2182,12 @@ static int soc_tplg_link_config(struct soc_tplg *tplg,
return ret;
}
+ /* for unloading it in snd_soc_tplg_component_remove */
+ link->dobj.index = tplg->index;
+ link->dobj.ops = tplg->ops;
+ link->dobj.type = SND_SOC_DOBJ_BACKEND_LINK;
+ list_add(&link->dobj.list, &tplg->comp->dobj_list);
+
return 0;
}
@@ -2649,6 +2674,13 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index)
case SND_SOC_DOBJ_DAI_LINK:
remove_link(comp, dobj, pass);
break;
+ case SND_SOC_DOBJ_BACKEND_LINK:
+ /*
+ * call link_unload ops if extra
+ * deinitialization is needed.
+ */
+ remove_backend_link(comp, dobj, pass);
+ break;
default:
dev_err(comp->dev, "ASoC: invalid component type %d for removal\n",
dobj->type);