|
Jiri Slaby |
221c28 |
From: Johan Hovold <johan+linaro@kernel.org>
|
|
Jiri Slaby |
221c28 |
Date: Mon, 6 Mar 2023 08:56:36 +0100
|
|
Jiri Slaby |
221c28 |
Subject: [PATCH] interconnect: qcom: rpm: fix registration race
|
|
Jiri Slaby |
221c28 |
References: bsc#1012628
|
|
Jiri Slaby |
221c28 |
Patch-mainline: 6.2.8
|
|
Jiri Slaby |
221c28 |
Git-commit: 90ae93d8affc1061cd87ca8ddd9a838c7d31a158
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
commit 90ae93d8affc1061cd87ca8ddd9a838c7d31a158 upstream.
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
The current interconnect provider registration interface is inherently
|
|
Jiri Slaby |
221c28 |
racy as nodes are not added until the after adding the provider. This
|
|
Jiri Slaby |
221c28 |
can specifically cause racing DT lookups to fail.
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
Switch to using the new API where the provider is not registered until
|
|
Jiri Slaby |
221c28 |
after it has been fully initialised.
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
Fixes: 62feb14ee8a3 ("interconnect: qcom: Consolidate interconnect RPM support")
|
|
Jiri Slaby |
221c28 |
Fixes: 30c8fa3ec61a ("interconnect: qcom: Add MSM8916 interconnect provider driver")
|
|
Jiri Slaby |
221c28 |
Cc: stable@vger.kernel.org # 5.7
|
|
Jiri Slaby |
221c28 |
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
|
|
Jiri Slaby |
221c28 |
Reviewed-by: Jun Nie <jun.nie@linaro.org>
|
|
Jiri Slaby |
221c28 |
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
|
|
Jiri Slaby |
221c28 |
Link: https://lore.kernel.org/r/20230306075651.2449-9-johan+linaro@kernel.org
|
|
Jiri Slaby |
221c28 |
Signed-off-by: Georgi Djakov <djakov@kernel.org>
|
|
Jiri Slaby |
221c28 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Jiri Slaby |
221c28 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
221c28 |
---
|
|
Jiri Slaby |
221c28 |
drivers/interconnect/qcom/icc-rpm.c | 24 ++++++++++++------------
|
|
Jiri Slaby |
221c28 |
1 file changed, 12 insertions(+), 12 deletions(-)
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c
|
|
Jiri Slaby |
221c28 |
index 91778cfc..4180a066 100644
|
|
Jiri Slaby |
221c28 |
--- a/drivers/interconnect/qcom/icc-rpm.c
|
|
Jiri Slaby |
221c28 |
+++ b/drivers/interconnect/qcom/icc-rpm.c
|
|
Jiri Slaby |
221c28 |
@@ -503,7 +503,6 @@ int qnoc_probe(struct platform_device *pdev)
|
|
Jiri Slaby |
221c28 |
}
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
provider = &qp->provider;
|
|
Jiri Slaby |
221c28 |
- INIT_LIST_HEAD(&provider->nodes);
|
|
Jiri Slaby |
221c28 |
provider->dev = dev;
|
|
Jiri Slaby |
221c28 |
provider->set = qcom_icc_set;
|
|
Jiri Slaby |
221c28 |
provider->pre_aggregate = qcom_icc_pre_bw_aggregate;
|
|
Jiri Slaby |
221c28 |
@@ -511,12 +510,7 @@ int qnoc_probe(struct platform_device *pdev)
|
|
Jiri Slaby |
221c28 |
provider->xlate_extended = qcom_icc_xlate_extended;
|
|
Jiri Slaby |
221c28 |
provider->data = data;
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
- ret = icc_provider_add(provider);
|
|
Jiri Slaby |
221c28 |
- if (ret) {
|
|
Jiri Slaby |
221c28 |
- dev_err(dev, "error adding interconnect provider: %d\n", ret);
|
|
Jiri Slaby |
221c28 |
- clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
|
Jiri Slaby |
221c28 |
- return ret;
|
|
Jiri Slaby |
221c28 |
- }
|
|
Jiri Slaby |
221c28 |
+ icc_provider_init(provider);
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
for (i = 0; i < num_nodes; i++) {
|
|
Jiri Slaby |
221c28 |
size_t j;
|
|
Jiri Slaby |
221c28 |
@@ -524,7 +518,7 @@ int qnoc_probe(struct platform_device *pdev)
|
|
Jiri Slaby |
221c28 |
node = icc_node_create(qnodes[i]->id);
|
|
Jiri Slaby |
221c28 |
if (IS_ERR(node)) {
|
|
Jiri Slaby |
221c28 |
ret = PTR_ERR(node);
|
|
Jiri Slaby |
221c28 |
- goto err;
|
|
Jiri Slaby |
221c28 |
+ goto err_remove_nodes;
|
|
Jiri Slaby |
221c28 |
}
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
node->name = qnodes[i]->name;
|
|
Jiri Slaby |
221c28 |
@@ -538,20 +532,26 @@ int qnoc_probe(struct platform_device *pdev)
|
|
Jiri Slaby |
221c28 |
}
|
|
Jiri Slaby |
221c28 |
data->num_nodes = num_nodes;
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
+ ret = icc_provider_register(provider);
|
|
Jiri Slaby |
221c28 |
+ if (ret)
|
|
Jiri Slaby |
221c28 |
+ goto err_remove_nodes;
|
|
Jiri Slaby |
221c28 |
+
|
|
Jiri Slaby |
221c28 |
platform_set_drvdata(pdev, qp);
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
/* Populate child NoC devices if any */
|
|
Jiri Slaby |
221c28 |
if (of_get_child_count(dev->of_node) > 0) {
|
|
Jiri Slaby |
221c28 |
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
|
|
Jiri Slaby |
221c28 |
if (ret)
|
|
Jiri Slaby |
221c28 |
- goto err;
|
|
Jiri Slaby |
221c28 |
+ goto err_deregister_provider;
|
|
Jiri Slaby |
221c28 |
}
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
return 0;
|
|
Jiri Slaby |
221c28 |
-err:
|
|
Jiri Slaby |
221c28 |
+
|
|
Jiri Slaby |
221c28 |
+err_deregister_provider:
|
|
Jiri Slaby |
221c28 |
+ icc_provider_deregister(provider);
|
|
Jiri Slaby |
221c28 |
+err_remove_nodes:
|
|
Jiri Slaby |
221c28 |
icc_nodes_remove(provider);
|
|
Jiri Slaby |
221c28 |
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
|
Jiri Slaby |
221c28 |
- icc_provider_del(provider);
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
return ret;
|
|
Jiri Slaby |
221c28 |
}
|
|
Jiri Slaby |
221c28 |
@@ -561,9 +561,9 @@ int qnoc_remove(struct platform_device *pdev)
|
|
Jiri Slaby |
221c28 |
{
|
|
Jiri Slaby |
221c28 |
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
+ icc_provider_deregister(&qp->provider);
|
|
Jiri Slaby |
221c28 |
icc_nodes_remove(&qp->provider);
|
|
Jiri Slaby |
221c28 |
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
|
|
Jiri Slaby |
221c28 |
- icc_provider_del(&qp->provider);
|
|
Jiri Slaby |
221c28 |
|
|
Jiri Slaby |
221c28 |
return 0;
|
|
Jiri Slaby |
221c28 |
}
|
|
Jiri Slaby |
221c28 |
--
|
|
Jiri Slaby |
221c28 |
2.35.3
|
|
Jiri Slaby |
221c28 |
|