ASoC: soc-core: call soc_bind_dai_link() under snd_soc_add_dai_link()
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tue, 5 Nov 2019 06:46:20 +0000 (15:46 +0900)
committerMark Brown <broonie@kernel.org>
Tue, 5 Nov 2019 23:50:01 +0000 (23:50 +0000)
If we focus to soc_bind_dai_link() at snd_soc_instantiate_card(),
we will notice very complex operation.

static int snd_soc_instantiate_card(...)
{
...
/*
 * (1) Bind dai_link via card pre-linked dai_link
 *
 * Bind dai_link via card pre-linked.
 * 1 dai_link will be 1 rtd, and connected to card.
 * for_each_card_prelinks() is for card pre-linked dai_link.
 *
 * Image
 *
 * card
 * - rtd(A)
 * - rtd(A)
 */
for_each_card_prelinks(card, i, dai_link) {
ret = soc_bind_dai_link(card, dai_link);
...
}
...
/*
 * (2) Connect card pre-linked dai_link to card list
 *
 * Connect all card pre-linked dai_link to *card list*.
 * Here, (A) means from card pre-linked.
 *
 * Image
 *
 * card card list
 *  - rtd(A)  - dai_link(A)
 *  - rtd(A)  - dai_link(A)
 *  - ...  - ...
 */
for_each_card_prelinks(card, i, dai_link) {
ret = snd_soc_add_dai_link(card, dai_link);
...
}
...
/*
 * (3) Probe binded component
 *
 * Each rtd has many components.
 * Here probes each rtd connected components.
 * rtd(A) in Image is the probe target.
 *
 * During this component probe, topology may add new dai_link to
 * *card list* by using snd_soc_add_dai_link() which is
 * used at (2).
 * Here, (B) means from topology
 *
 * Image
 *
 * card card list
 *  - rtd(A)  - dai_link(A)
 *  - rtd(A)  - dai_link(A)
 *  - ...  - ...
 *  - dai_link(B)
 *  - dai_link(B)
 */
ret = soc_probe_link_components(card);
...

/*
 * (4) Bind dai_link again
 *
 * Bind dai_link again for topology.
 * Note, (1) used for_each_card_prelinks(),
 * here is using  for_each_card_links()
 *
 * This means from card list.
 * As Image indicating, it has dai_link(A) (from card pre-link)
 * and dai_link(B) (from topology).
 * main target here is dai_link(B).
 * soc_bind_dai_link() ignores already used
 * dai_link (= dai_link(A))
 *
 * Image
 *
 * card card list
 *  - rtd(A)  - dai_link(A)
 *  - rtd(A)  - dai_link(A)
 *  - ...  - ...
 *  - rtd(B)  - dai_link(B)
 *  - rtd(B)  - dai_link(B)
 */
for_each_card_links(card, dai_link) {
ret = soc_bind_dai_link(card, dai_link);
...
}
...
}

As you see above, it is doing very complex method.
The problem is binding dai_link via "card pre-linked" (= (1)) and
"topology added dai_link" (= (3)) are separated.
The code can be simple if we can bind dai_link when dai_link
is connected to *card list*.
This patch do it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/878sou3jnn.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/soc-core.c

index 3cc36c2d99dac5ee0e0891fe37e4c32b9089f5f0..e8ff6f2f58ba5a27235390f7a77c21ff6b67432e 100644 (file)
@@ -1409,6 +1409,8 @@ EXPORT_SYMBOL_GPL(snd_soc_disconnect_sync);
 int snd_soc_add_dai_link(struct snd_soc_card *card,
                struct snd_soc_dai_link *dai_link)
 {
+       int ret;
+
        if (dai_link->dobj.type
            && dai_link->dobj.type != SND_SOC_DOBJ_DAI_LINK) {
                dev_err(card->dev, "Invalid dai link type %d\n",
@@ -1424,6 +1426,10 @@ int snd_soc_add_dai_link(struct snd_soc_card *card,
        if (dai_link->dobj.type && card->add_dai_link)
                card->add_dai_link(card, dai_link);
 
+       ret = soc_bind_dai_link(card, dai_link);
+       if (ret < 0)
+               return ret;
+
        /* see for_each_card_links */
        list_add_tail(&dai_link->list, &card->dai_link_list);
 
@@ -1996,13 +2002,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
        /* check whether any platform is ignore machine FE and using topology */
        soc_check_tplg_fes(card);
 
-       /* bind DAIs */
-       for_each_card_prelinks(card, i, dai_link) {
-               ret = soc_bind_dai_link(card, dai_link);
-               if (ret != 0)
-                       goto probe_end;
-       }
-
        /* bind aux_devs too */
        ret = soc_bind_aux_dev(card);
        if (ret < 0)
@@ -2060,16 +2059,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
        if (ret < 0)
                goto probe_end;
 
-       /*
-        * Find new DAI links added during probing components and bind them.
-        * Components with topology may bring new DAIs and DAI links.
-        */
-       for_each_card_links(card, dai_link) {
-               ret = soc_bind_dai_link(card, dai_link);
-               if (ret)
-                       goto probe_end;
-       }
-
        /* probe all DAI links on this card */
        ret = soc_probe_link_dais(card);
        if (ret < 0) {