Commit a8009a59 authored by Takashi Iwai's avatar Takashi Iwai Committed by Kleber Sacilotto de Souza

ASoC: qcom: Fix of-node refcount unbalance in apq8016_sbc_parse_of()

BugLink: https://bugs.launchpad.net/bugs/1864773

[ Upstream commit 8d166720 ]

The apq8016 driver leaves the of-node refcount at aborting from the
loop of for_each_child_of_node() in the error path.  Not only the
iterator node of for_each_child_of_node(), the children nodes referred
from it for codec and cpu have to be properly unreferenced.

Fixes: bdb052e8 ("ASoC: qcom: add apq8016 sound card support")
Cc: Patrick Lai <plai@codeaurora.org>
Cc: Banajit Goswami <bgoswami@codeaurora.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
parent 520b87d8
...@@ -98,13 +98,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) ...@@ -98,13 +98,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
if (!cpu || !codec) { if (!cpu || !codec) {
dev_err(dev, "Can't find cpu/codec DT node\n"); dev_err(dev, "Can't find cpu/codec DT node\n");
return ERR_PTR(-EINVAL); ret = -EINVAL;
goto error;
} }
link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0); link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
if (!link->cpu_of_node) { if (!link->cpu_of_node) {
dev_err(card->dev, "error getting cpu phandle\n"); dev_err(card->dev, "error getting cpu phandle\n");
return ERR_PTR(-EINVAL); ret = -EINVAL;
goto error;
} }
link->codec_of_node = of_parse_phandle(codec, "sound-dai", 0); link->codec_of_node = of_parse_phandle(codec, "sound-dai", 0);
...@@ -116,13 +118,13 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) ...@@ -116,13 +118,13 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name); ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
if (ret) { if (ret) {
dev_err(card->dev, "error getting cpu dai name\n"); dev_err(card->dev, "error getting cpu dai name\n");
return ERR_PTR(ret); goto error;
} }
ret = snd_soc_of_get_dai_name(codec, &link->codec_dai_name); ret = snd_soc_of_get_dai_name(codec, &link->codec_dai_name);
if (ret) { if (ret) {
dev_err(card->dev, "error getting codec dai name\n"); dev_err(card->dev, "error getting codec dai name\n");
return ERR_PTR(ret); goto error;
} }
link->platform_of_node = link->cpu_of_node; link->platform_of_node = link->cpu_of_node;
...@@ -132,15 +134,24 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) ...@@ -132,15 +134,24 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
ret = of_property_read_string(np, "link-name", &link->name); ret = of_property_read_string(np, "link-name", &link->name);
if (ret) { if (ret) {
dev_err(card->dev, "error getting codec dai_link name\n"); dev_err(card->dev, "error getting codec dai_link name\n");
return ERR_PTR(ret); goto error;
} }
link->stream_name = link->name; link->stream_name = link->name;
link->init = apq8016_sbc_dai_init; link->init = apq8016_sbc_dai_init;
link++; link++;
of_node_put(cpu);
of_node_put(codec);
} }
return data; return data;
error:
of_node_put(np);
of_node_put(cpu);
of_node_put(codec);
return ERR_PTR(ret);
} }
static int apq8016_sbc_platform_probe(struct platform_device *pdev) static int apq8016_sbc_platform_probe(struct platform_device *pdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment