ASoC: qcom: apq8016_sbc: Fix oops with multiple DAI links
authorStephan Gerhold <stephan@gerhold.net>
Mon, 22 Jul 2019 13:03:52 +0000 (15:03 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 23 Jul 2019 11:16:29 +0000 (12:16 +0100)
apq8016_sbc_parse_of() sets up multiple DAI links, depending on the
number of nodes in the device tree. However, at the moment
CPU and platform components are only allocated for the first link.
This causes an oops when more than one link is defined:

Internal error: Oops: 96000044 [#1] SMP
CPU: 0 PID: 1015 Comm: kworker/0:2 Not tainted 5.3.0-rc1 #4
Call trace:
 apq8016_sbc_platform_probe+0x1a8/0x3f0
 platform_drv_probe+0x50/0xa0
...

Move the allocation inside the loop to ensure that each link is
properly initialized.

Fixes: 98b232ca9e0e ("ASoC: qcom: apq8016_sbc: use modern dai_link style")
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/20190722130352.95874-1-stephan@gerhold.net
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/qcom/apq8016_sbc.c

index f60a71990f662acd40ea1e5cd22bc43464a4eba7..ac75838bbfabe9ec24974571a6761e5fa63ed5d7 100644 (file)
@@ -150,17 +150,17 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
 
        link = data->dai_link;
 
-       dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
-       if (!dlc)
-               return ERR_PTR(-ENOMEM);
+       for_each_child_of_node(node, np) {
+               dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
+               if (!dlc)
+                       return ERR_PTR(-ENOMEM);
 
-       link->cpus      = &dlc[0];
-       link->platforms = &dlc[1];
+               link->cpus      = &dlc[0];
+               link->platforms = &dlc[1];
 
-       link->num_cpus          = 1;
-       link->num_platforms     = 1;
+               link->num_cpus          = 1;
+               link->num_platforms     = 1;
 
-       for_each_child_of_node(node, np) {
                cpu = of_get_child_by_name(np, "cpu");
                codec = of_get_child_by_name(np, "codec");