Skip to content

Commit 5b577d2

Browse files
Keryerbroonie
authored andcommitted
ASoC: davinci-evm: Fix reference leak in davinci_evm_probe
The davinci_evm_probe() function calls of_parse_phandle() to acquire device nodes for "ti,audio-codec" and "ti,mcasp-controller". These functions return device nodes with incremented reference counts. However, in several error paths (e.g., when the second of_parse_phandle(), snd_soc_of_parse_card_name(), or devm_snd_soc_register_card() fails), the function returns directly without releasing the acquired nodes, leading to reference leaks. This patch adds an error handling path 'err_put' to properly release the device nodes using of_node_put() and clean up the pointers when an error occurs. Signed-off-by: Kery Qi <qikeyu2017@gmail.com> Link: https://patch.msgid.link/20260107154836.1521-2-qikeyu2017@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 2fa0eaf commit 5b577d2

1 file changed

Lines changed: 31 additions & 8 deletions

File tree

sound/soc/ti/davinci-evm.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,27 +194,32 @@ static int davinci_evm_probe(struct platform_device *pdev)
194194
return -EINVAL;
195195

196196
dai->cpus->of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
197-
if (!dai->cpus->of_node)
198-
return -EINVAL;
197+
if (!dai->cpus->of_node) {
198+
ret = -EINVAL;
199+
goto err_put;
200+
}
199201

200202
dai->platforms->of_node = dai->cpus->of_node;
201203

202204
evm_soc_card.dev = &pdev->dev;
203205
ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
204206
if (ret)
205-
return ret;
207+
goto err_put;
206208

207209
mclk = devm_clk_get(&pdev->dev, "mclk");
208210
if (PTR_ERR(mclk) == -EPROBE_DEFER) {
209-
return -EPROBE_DEFER;
211+
ret = -EPROBE_DEFER;
212+
goto err_put;
210213
} else if (IS_ERR(mclk)) {
211214
dev_dbg(&pdev->dev, "mclk not found.\n");
212215
mclk = NULL;
213216
}
214217

215218
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
216-
if (!drvdata)
217-
return -ENOMEM;
219+
if (!drvdata) {
220+
ret = -ENOMEM;
221+
goto err_put;
222+
}
218223

219224
drvdata->mclk = mclk;
220225

@@ -224,7 +229,8 @@ static int davinci_evm_probe(struct platform_device *pdev)
224229
if (!drvdata->mclk) {
225230
dev_err(&pdev->dev,
226231
"No clock or clock rate defined.\n");
227-
return -EINVAL;
232+
ret = -EINVAL;
233+
goto err_put;
228234
}
229235
drvdata->sysclk = clk_get_rate(drvdata->mclk);
230236
} else if (drvdata->mclk) {
@@ -240,8 +246,25 @@ static int davinci_evm_probe(struct platform_device *pdev)
240246
snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
241247
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
242248

243-
if (ret)
249+
if (ret) {
244250
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
251+
goto err_put;
252+
}
253+
254+
return ret;
255+
256+
err_put:
257+
dai->platforms->of_node = NULL;
258+
259+
if (dai->cpus->of_node) {
260+
of_node_put(dai->cpus->of_node);
261+
dai->cpus->of_node = NULL;
262+
}
263+
264+
if (dai->codecs->of_node) {
265+
of_node_put(dai->codecs->of_node);
266+
dai->codecs->of_node = NULL;
267+
}
245268

246269
return ret;
247270
}

0 commit comments

Comments
 (0)