interconnect: fix error handling in qnoc_probe()
authorYang Yingliang <yangyingliang@huawei.com>
Thu, 3 Aug 2023 13:05:21 +0000 (21:05 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 20 Nov 2023 10:59:27 +0000 (11:59 +0100)
[ Upstream commit 273f74a2e7d15a5c216a4a26b84b1563c7092c9d ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/interconnect/qcom/icc-rpm.c

index 2c16917..e76356f 100644 (file)
@@ -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;