mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
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>
This commit is contained in:
parent
2fa0eaf78c
commit
5b577d214f
|
|
@ -194,27 +194,32 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
|
||||
dai->cpus->of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
|
||||
if (!dai->cpus->of_node)
|
||||
return -EINVAL;
|
||||
if (!dai->cpus->of_node) {
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
dai->platforms->of_node = dai->cpus->of_node;
|
||||
|
||||
evm_soc_card.dev = &pdev->dev;
|
||||
ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_put;
|
||||
|
||||
mclk = devm_clk_get(&pdev->dev, "mclk");
|
||||
if (PTR_ERR(mclk) == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
ret = -EPROBE_DEFER;
|
||||
goto err_put;
|
||||
} else if (IS_ERR(mclk)) {
|
||||
dev_dbg(&pdev->dev, "mclk not found.\n");
|
||||
mclk = NULL;
|
||||
}
|
||||
|
||||
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
if (!drvdata) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
drvdata->mclk = mclk;
|
||||
|
||||
|
|
@ -224,7 +229,8 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
|||
if (!drvdata->mclk) {
|
||||
dev_err(&pdev->dev,
|
||||
"No clock or clock rate defined.\n");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto err_put;
|
||||
}
|
||||
drvdata->sysclk = clk_get_rate(drvdata->mclk);
|
||||
} else if (drvdata->mclk) {
|
||||
|
|
@ -240,8 +246,25 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
|||
snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
|
||||
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_put:
|
||||
dai->platforms->of_node = NULL;
|
||||
|
||||
if (dai->cpus->of_node) {
|
||||
of_node_put(dai->cpus->of_node);
|
||||
dai->cpus->of_node = NULL;
|
||||
}
|
||||
|
||||
if (dai->codecs->of_node) {
|
||||
of_node_put(dai->codecs->of_node);
|
||||
dai->codecs->of_node = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user