summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Novikov <novikov@ispras.ru>2021-07-10 15:04:32 +0300
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-07-22 15:01:55 +0300
commit055d2db28ec2fa3ab5c527c5604f1b32b89fa13a (patch)
tree12f22d0789b81bf640316b76adf769653bdb504c
parent514e97674400462cc09c459a1ddfb9bf39017223 (diff)
downloadlinux-055d2db28ec2fa3ab5c527c5604f1b32b89fa13a.tar.xz
media: platform: stm32: unprepare clocks at handling errors in probe
stm32_cec_probe() did not unprepare clocks on error handling paths. The patch fixes that. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Evgeny Novikov <novikov@ispras.ru> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--drivers/media/cec/platform/stm32/stm32-cec.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/media/cec/platform/stm32/stm32-cec.c b/drivers/media/cec/platform/stm32/stm32-cec.c
index ea4b1ebfca99..0ffd89712536 100644
--- a/drivers/media/cec/platform/stm32/stm32-cec.c
+++ b/drivers/media/cec/platform/stm32/stm32-cec.c
@@ -305,14 +305,16 @@ static int stm32_cec_probe(struct platform_device *pdev)
cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
if (IS_ERR(cec->clk_hdmi_cec) &&
- PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_unprepare_cec_clk;
+ }
if (!IS_ERR(cec->clk_hdmi_cec)) {
ret = clk_prepare(cec->clk_hdmi_cec);
if (ret) {
dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n");
- return ret;
+ goto err_unprepare_cec_clk;
}
}
@@ -324,19 +326,27 @@ static int stm32_cec_probe(struct platform_device *pdev)
CEC_NAME, caps, CEC_MAX_LOG_ADDRS);
ret = PTR_ERR_OR_ZERO(cec->adap);
if (ret)
- return ret;
+ goto err_unprepare_hdmi_cec_clk;
ret = cec_register_adapter(cec->adap, &pdev->dev);
- if (ret) {
- cec_delete_adapter(cec->adap);
- return ret;
- }
+ if (ret)
+ goto err_delete_adapter;
cec_hw_init(cec);
platform_set_drvdata(pdev, cec);
return 0;
+
+err_delete_adapter:
+ cec_delete_adapter(cec->adap);
+
+err_unprepare_hdmi_cec_clk:
+ clk_unprepare(cec->clk_hdmi_cec);
+
+err_unprepare_cec_clk:
+ clk_unprepare(cec->clk_cec);
+ return ret;
}
static int stm32_cec_remove(struct platform_device *pdev)