| From 0f7c11ad0d275337ef8c188b7d8757801a905173 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 19 Feb 2019 16:46:50 +0100 |
| Subject: ASoC: qcom: Fix of-node refcount unbalance in apq8016_sbc_parse_of() |
| |
| From: Takashi Iwai <tiwai@suse.de> |
| |
| [ Upstream commit 8d1667200850f8753c0265fa4bd25c9a6e5f94ce ] |
| |
| 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: bdb052e81f62 ("ASoC: qcom: add apq8016 sound card support") |
| Cc: Patrick Lai <plai@codeaurora.org> |
| Cc: Banajit Goswami <bgoswami@codeaurora.org> |
| Signed-off-by: Takashi Iwai <tiwai@suse.de> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/soc/qcom/apq8016_sbc.c | 21 ++++++++++++++++----- |
| 1 file changed, 16 insertions(+), 5 deletions(-) |
| |
| diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c |
| index 07f91e918b234..754742018515a 100644 |
| --- a/sound/soc/qcom/apq8016_sbc.c |
| +++ b/sound/soc/qcom/apq8016_sbc.c |
| @@ -114,13 +114,15 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) |
| |
| if (!cpu || !codec) { |
| 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); |
| if (!link->cpu_of_node) { |
| 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); |
| @@ -132,28 +134,37 @@ 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); |
| if (ret) { |
| 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); |
| if (ret) { |
| dev_err(card->dev, "error getting codec dai name\n"); |
| - return ERR_PTR(ret); |
| + goto error; |
| } |
| |
| link->platform_of_node = link->cpu_of_node; |
| ret = of_property_read_string(np, "link-name", &link->name); |
| if (ret) { |
| dev_err(card->dev, "error getting codec dai_link name\n"); |
| - return ERR_PTR(ret); |
| + goto error; |
| } |
| |
| link->stream_name = link->name; |
| link->init = apq8016_sbc_dai_init; |
| link++; |
| + |
| + of_node_put(cpu); |
| + of_node_put(codec); |
| } |
| |
| return data; |
| + |
| + error: |
| + of_node_put(np); |
| + of_node_put(cpu); |
| + of_node_put(codec); |
| + return ERR_PTR(ret); |
| } |
| |
| static const struct snd_soc_dapm_widget apq8016_sbc_dapm_widgets[] = { |
| -- |
| 2.20.1 |
| |