ASoC: simple-card: Fix breakage on kontron-sl28-var3-ads2
authorMark Brown <broonie@kernel.org>
Fri, 23 Apr 2021 17:07:54 +0000 (18:07 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 23 Apr 2021 17:13:32 +0000 (18:13 +0100)
A KernelCI bisection identified 59c35c44a9cf89 "ASoC: simple-card: add
simple_parse_node()" as causing simple-card to fail to instantiate on
kontron-sl28-var3-ads2 systems.  Since the merge window is expected to
open over the weekend drop that commit and subsequent ones which depend
on it for now in case other systems are affected too.

The boot log showed the error as:

<4>[    9.948821] sysfs: cannot create duplicate filename '/devices/platform/sound/(null)-wm8904-hifi'

(backtrace)

<3>[   10.191982] kobject_add_internal failed for (null)-wm8904-hifi with -EEXIST, don't try to register things with the same name in the same directory.

The dropped commits are:

73371bacf0475a20ab6 "ASoC: audio-graph: tidyup graph_dai_link_of_dpcm()"
434392271afcff350fe "ASoC: simple-card: add simple_link_init()"
59c35c44a9cf89a83a9 "ASoC: simple-card: add simple_parse_node()"

Reported-by: Guillaume Tucker <guillaume.tucker@collabora.com>
Reported-by: "kernelci.org bot" <bot@kernelci.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/generic/audio-graph-card.c
sound/soc/generic/simple-card.c

index 0159a4576e9c1e26a1072e917d0ddabb887c24d0..2c8a2fcb7922a24841507136e7aec24587a4581f 100644 (file)
@@ -276,19 +276,24 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
                                  struct link_info *li)
 {
        struct device *dev = simple_priv_to_dev(priv);
+       struct snd_soc_card *card = simple_priv_to_card(priv);
        struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
        struct device_node *top = dev->of_node;
        struct device_node *ep = li->cpu ? cpu_ep : codec_ep;
+       struct device_node *port;
+       struct device_node *ports;
+       struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0);
+       struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);
        char dai_name[64];
        int ret;
 
+       port    = of_get_parent(ep);
+       ports   = of_get_parent(port);
+
        dev_dbg(dev, "link_of DPCM (%pOF)\n", ep);
 
        if (li->cpu) {
-               struct snd_soc_card *card = simple_priv_to_card(priv);
-               struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0);
-
                /* Codec is dummy */
 
                /* FE settings */
@@ -297,7 +302,7 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
 
                ret = graph_parse_node(priv, cpu_ep, li, 1);
                if (ret)
-                       return ret;
+                       goto out_put_node;
 
                snprintf(dai_name, sizeof(dai_name),
                         "fe.%pOFP.%s", cpus->of_node, cpus->dai_name);
@@ -314,10 +319,7 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
                if (card->component_chaining && !soc_component_is_pcm(cpus))
                        dai_link->no_pcm = 1;
        } else {
-               struct snd_soc_codec_conf *cconf = simple_props_to_codec_conf(dai_props, 0);
-               struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);
-               struct device_node *port;
-               struct device_node *ports;
+               struct snd_soc_codec_conf *cconf;
 
                /* CPU is dummy */
 
@@ -325,25 +327,22 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
                dai_link->no_pcm                = 1;
                dai_link->be_hw_params_fixup    = asoc_simple_be_hw_params_fixup;
 
+               cconf   = simple_props_to_codec_conf(dai_props, 0);
+
                ret = graph_parse_node(priv, codec_ep, li, 0);
                if (ret < 0)
-                       return ret;
+                       goto out_put_node;
 
                snprintf(dai_name, sizeof(dai_name),
                         "be.%pOFP.%s", codecs->of_node, codecs->dai_name);
 
                /* check "prefix" from top node */
-               port = of_get_parent(ep);
-               ports = of_get_parent(port);
                snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,
                                              "prefix");
                if (of_node_name_eq(ports, "ports"))
                        snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node, "prefix");
                snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node,
                                             "prefix");
-
-               of_node_put(ports);
-               of_node_put(port);
        }
 
        graph_parse_convert(dev, ep, &dai_props->adata);
@@ -352,8 +351,11 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
 
        ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name);
 
+out_put_node:
        li->link++;
 
+       of_node_put(ports);
+       of_node_put(port);
        return ret;
 }
 
index 6a04632944b8179eea11743031818a0aeaf8d7b9..a1373be4558f3f40faf84a37b4b69d6249737453 100644 (file)
@@ -93,11 +93,12 @@ static void simple_parse_convert(struct device *dev,
 }
 
 static void simple_parse_mclk_fs(struct device_node *top,
-                                struct device_node *np,
+                                struct device_node *cpu,
+                                struct device_node *codec,
                                 struct simple_dai_props *props,
                                 char *prefix)
 {
-       struct device_node *node = of_get_parent(np);
+       struct device_node *node = of_get_parent(cpu);
        char prop[128];
 
        snprintf(prop, sizeof(prop), "%smclk-fs", PREFIX);
@@ -105,79 +106,12 @@ static void simple_parse_mclk_fs(struct device_node *top,
 
        snprintf(prop, sizeof(prop), "%smclk-fs", prefix);
        of_property_read_u32(node,      prop, &props->mclk_fs);
-       of_property_read_u32(np,        prop, &props->mclk_fs);
+       of_property_read_u32(cpu,       prop, &props->mclk_fs);
+       of_property_read_u32(codec,     prop, &props->mclk_fs);
 
        of_node_put(node);
 }
 
-static int simple_parse_node(struct asoc_simple_priv *priv,
-                            struct device_node *np,
-                            struct link_info *li,
-                            char *prefix,
-                            int is_cpu)
-{
-       struct device *dev = simple_priv_to_dev(priv);
-       struct device_node *top = dev->of_node;
-       struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
-       struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
-       struct snd_soc_dai_link_component *dlc;
-       struct asoc_simple_dai *dai;
-       int ret, single = 0;
-
-       if (is_cpu) {
-               dlc = asoc_link_to_cpu(dai_link, 0);
-               dai = simple_props_to_dai_cpu(dai_props, 0);
-       } else {
-               dlc = asoc_link_to_codec(dai_link, 0);
-               dai = simple_props_to_dai_codec(dai_props, 0);
-       }
-
-       simple_parse_mclk_fs(top, np, dai_props, prefix);
-
-       ret = asoc_simple_parse_dai(np, dlc, &single);
-       if (ret)
-               return ret;
-
-       ret = asoc_simple_parse_clk(dev, np, dai, dlc);
-       if (ret)
-               return ret;
-
-       ret = asoc_simple_parse_tdm(np, dai);
-       if (ret)
-               return ret;
-
-       if (is_cpu) {
-               struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0);
-
-               asoc_simple_canonicalize_cpu(dlc, single);
-               asoc_simple_canonicalize_platform(platforms, dlc);
-       }
-
-       return 0;
-}
-
-static int simple_link_init(struct asoc_simple_priv *priv,
-                           struct device_node *node,
-                           struct device_node *codec,
-                           struct link_info *li,
-                           char *prefix,
-                           char *name)
-{
-       struct device *dev = simple_priv_to_dev(priv);
-       struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
-       int ret;
-
-       ret = asoc_simple_parse_daifmt(dev, node, codec,
-                                      prefix, &dai_link->dai_fmt);
-       if (ret < 0)
-               return 0;
-
-       dai_link->init                  = asoc_simple_dai_init;
-       dai_link->ops                   = &simple_ops;
-
-       return asoc_simple_set_dailink_name(dev, dai_link, name);
-}
-
 static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
                                   struct device_node *np,
                                   struct device_node *codec,
@@ -187,32 +121,50 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
        struct device *dev = simple_priv_to_dev(priv);
        struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
+       struct asoc_simple_dai *dai;
        struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0);
        struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);
+       struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0);
        struct device_node *top = dev->of_node;
        struct device_node *node = of_get_parent(np);
        char *prefix = "";
-       char dai_name[64];
        int ret;
 
        dev_dbg(dev, "link_of DPCM (%pOF)\n", np);
 
+       li->link++;
+
        /* For single DAI link & old style of DT node */
        if (is_top)
                prefix = PREFIX;
 
        if (li->cpu) {
+               int is_single_links = 0;
+
                /* Codec is dummy */
 
                /* FE settings */
                dai_link->dynamic               = 1;
                dai_link->dpcm_merged_format    = 1;
 
-               ret = simple_parse_node(priv, np, li, prefix, 1);
+               dai = simple_props_to_dai_cpu(dai_props, 0);
+
+               ret = asoc_simple_parse_dai(np, cpus, &is_single_links);
+               if (ret)
+                       goto out_put_node;
+
+               ret = asoc_simple_parse_clk(dev, np, dai, cpus);
                if (ret < 0)
                        goto out_put_node;
 
-               snprintf(dai_name, sizeof(dai_name), "fe.%s", cpus->dai_name);
+               ret = asoc_simple_set_dailink_name(dev, dai_link,
+                                                  "fe.%s",
+                                                  cpus->dai_name);
+               if (ret < 0)
+                       goto out_put_node;
+
+               asoc_simple_canonicalize_cpu(cpus, is_single_links);
+               asoc_simple_canonicalize_platform(platforms, cpus);
        } else {
                struct snd_soc_codec_conf *cconf;
 
@@ -222,13 +174,22 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
                dai_link->no_pcm                = 1;
                dai_link->be_hw_params_fixup    = asoc_simple_be_hw_params_fixup;
 
+               dai     = simple_props_to_dai_codec(dai_props, 0);
                cconf   = simple_props_to_codec_conf(dai_props, 0);
 
-               ret = simple_parse_node(priv, np, li, prefix, 0);
+               ret = asoc_simple_parse_dai(np, codecs, NULL);
+               if (ret < 0)
+                       goto out_put_node;
+
+               ret = asoc_simple_parse_clk(dev, np, dai, codecs);
                if (ret < 0)
                        goto out_put_node;
 
-               snprintf(dai_name, sizeof(dai_name), "be.%s", codecs->dai_name);
+               ret = asoc_simple_set_dailink_name(dev, dai_link,
+                                                  "be.%s",
+                                                  codecs->dai_name);
+               if (ret < 0)
+                       goto out_put_node;
 
                /* check "prefix" from top node */
                snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,
@@ -240,14 +201,23 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
        }
 
        simple_parse_convert(dev, np, &dai_props->adata);
+       simple_parse_mclk_fs(top, np, codec, dai_props, prefix);
+
+       ret = asoc_simple_parse_tdm(np, dai);
+       if (ret)
+               goto out_put_node;
+
+       ret = asoc_simple_parse_daifmt(dev, node, codec,
+                                      prefix, &dai_link->dai_fmt);
+       if (ret < 0)
+               goto out_put_node;
 
        snd_soc_dai_link_set_capabilities(dai_link);
 
-       ret = simple_link_init(priv, node, codec, li, prefix, dai_name);
+       dai_link->ops                   = &simple_ops;
+       dai_link->init                  = asoc_simple_dai_init;
 
 out_put_node:
-       li->link++;
-
        of_node_put(node);
        return ret;
 }
@@ -260,19 +230,23 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,
 {
        struct device *dev = simple_priv_to_dev(priv);
        struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
+       struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
+       struct asoc_simple_dai *cpu_dai = simple_props_to_dai_cpu(dai_props, 0);
+       struct asoc_simple_dai *codec_dai = simple_props_to_dai_codec(dai_props, 0);
        struct snd_soc_dai_link_component *cpus = asoc_link_to_cpu(dai_link, 0);
        struct snd_soc_dai_link_component *codecs = asoc_link_to_codec(dai_link, 0);
        struct snd_soc_dai_link_component *platforms = asoc_link_to_platform(dai_link, 0);
+       struct device_node *top = dev->of_node;
        struct device_node *cpu = NULL;
        struct device_node *node = NULL;
        struct device_node *plat = NULL;
-       char dai_name[64];
        char prop[128];
        char *prefix = "";
-       int ret;
+       int ret, single_cpu = 0;
 
        cpu  = np;
        node = of_get_parent(np);
+       li->link++;
 
        dev_dbg(dev, "link_of (%pOF)\n", node);
 
@@ -283,11 +257,18 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,
        snprintf(prop, sizeof(prop), "%splat", prefix);
        plat = of_get_child_by_name(node, prop);
 
-       ret = simple_parse_node(priv, cpu, li, prefix, 1);
+       ret = asoc_simple_parse_daifmt(dev, node, codec,
+                                      prefix, &dai_link->dai_fmt);
        if (ret < 0)
                goto dai_link_of_err;
 
-       ret = simple_parse_node(priv, codec, li, prefix, 0);
+       simple_parse_mclk_fs(top, cpu, codec, dai_props, prefix);
+
+       ret = asoc_simple_parse_dai(cpu, cpus, &single_cpu);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = asoc_simple_parse_dai(codec, codecs, NULL);
        if (ret < 0)
                goto dai_link_of_err;
 
@@ -295,18 +276,39 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,
        if (ret < 0)
                goto dai_link_of_err;
 
-       snprintf(dai_name, sizeof(dai_name),
-                "%s-%s", cpus->dai_name, codecs->dai_name);
-       ret = simple_link_init(priv, node, codec, li, prefix, dai_name);
+       ret = asoc_simple_parse_tdm(cpu, cpu_dai);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = asoc_simple_parse_tdm(codec, codec_dai);
        if (ret < 0)
                goto dai_link_of_err;
 
+       ret = asoc_simple_parse_clk(dev, cpu, cpu_dai, cpus);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = asoc_simple_parse_clk(dev, codec, codec_dai, codecs);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = asoc_simple_set_dailink_name(dev, dai_link,
+                                          "%s-%s",
+                                          cpus->dai_name,
+                                          codecs->dai_name);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       dai_link->ops = &simple_ops;
+       dai_link->init = asoc_simple_dai_init;
+
+       asoc_simple_canonicalize_cpu(cpus, single_cpu);
+       asoc_simple_canonicalize_platform(platforms, cpus);
+
 dai_link_of_err:
        of_node_put(plat);
        of_node_put(node);
 
-       li->link++;
-
        return ret;
 }