summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYang Yingliang <yangyingliang@huawei.com>2023-08-03 21:05:21 +0800
committerGeorgi Djakov <djakov@kernel.org>2023-10-10 14:10:36 +0300
commit273f74a2e7d15a5c216a4a26b84b1563c7092c9d (patch)
tree69ce21ed740c272ee5120e9d7aa10709918c63d2
parent577a3c5af1fe87b65931ea94d5515266da301f56 (diff)
downloadlinux-273f74a2e7d15a5c216a4a26b84b1563c7092c9d.tar.gz
linux-273f74a2e7d15a5c216a4a26b84b1563c7092c9d.tar.bz2
linux-273f74a2e7d15a5c216a4a26b84b1563c7092c9d.zip
interconnect: fix error handling in qnoc_probe()
Add missing clk_disable_unprepare() and clk_bulk_disable_unprepare() in the error path in qnoc_probe(). And when qcom_icc_qos_set() fails, it needs remove nodes and disable clks. Fixes: 2e2113c8a64f ("interconnect: qcom: rpm: Handle interface clocks") Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Link: https://lore.kernel.org/r/20230803130521.959487-1-yangyingliang@huawei.com Signed-off-by: Georgi Djakov <djakov@kernel.org>
-rw-r--r--drivers/interconnect/qcom/icc-rpm.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c
index 2c16917ba1fd..e76356f91125 100644
--- a/drivers/interconnect/qcom/icc-rpm.c
+++ b/drivers/interconnect/qcom/icc-rpm.c
@@ -497,7 +497,7 @@ regmap_done:
ret = devm_clk_bulk_get(dev, qp->num_intf_clks, qp->intf_clks);
if (ret)
- return ret;
+ goto err_disable_unprepare_clk;
provider = &qp->provider;
provider->dev = dev;
@@ -512,13 +512,15 @@ regmap_done:
/* If this fails, bus accesses will crash the platform! */
ret = clk_bulk_prepare_enable(qp->num_intf_clks, qp->intf_clks);
if (ret)
- return ret;
+ goto err_disable_unprepare_clk;
for (i = 0; i < num_nodes; i++) {
size_t j;
node = icc_node_create(qnodes[i]->id);
if (IS_ERR(node)) {
+ clk_bulk_disable_unprepare(qp->num_intf_clks,
+ qp->intf_clks);
ret = PTR_ERR(node);
goto err_remove_nodes;
}
@@ -534,8 +536,11 @@ regmap_done:
if (qnodes[i]->qos.ap_owned &&
qnodes[i]->qos.qos_mode != NOC_QOS_MODE_INVALID) {
ret = qcom_icc_qos_set(node);
- if (ret)
- return ret;
+ if (ret) {
+ clk_bulk_disable_unprepare(qp->num_intf_clks,
+ qp->intf_clks);
+ goto err_remove_nodes;
+ }
}
data->nodes[i] = node;
@@ -563,6 +568,7 @@ err_deregister_provider:
icc_provider_deregister(provider);
err_remove_nodes:
icc_nodes_remove(provider);
+err_disable_unprepare_clk:
clk_disable_unprepare(qp->bus_clk);
return ret;