Skip to content

Commit 74240a5

Browse files
jhovoldGeorgi Djakov
authored andcommitted
interconnect: qcom: rpmh: fix registration race
The current interconnect provider registration interface is inherently racy as nodes are not added until the after adding the provider. This can specifically cause racing DT lookups to fail. Switch to using the new API where the provider is not registered until after it has been fully initialised. Fixes: 976daac ("interconnect: qcom: Consolidate interconnect RPMh support") Cc: [email protected] # 5.7 Reviewed-by: Konrad Dybcio <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Georgi Djakov <[email protected]>
1 parent 6570d1d commit 74240a5

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

drivers/interconnect/qcom/icc-rpmh.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,10 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
192192
provider->pre_aggregate = qcom_icc_pre_aggregate;
193193
provider->aggregate = qcom_icc_aggregate;
194194
provider->xlate_extended = qcom_icc_xlate_extended;
195-
INIT_LIST_HEAD(&provider->nodes);
196195
provider->data = data;
197196

197+
icc_provider_init(provider);
198+
198199
qp->dev = dev;
199200
qp->bcms = desc->bcms;
200201
qp->num_bcms = desc->num_bcms;
@@ -203,10 +204,6 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
203204
if (IS_ERR(qp->voter))
204205
return PTR_ERR(qp->voter);
205206

206-
ret = icc_provider_add(provider);
207-
if (ret)
208-
return ret;
209-
210207
for (i = 0; i < qp->num_bcms; i++)
211208
qcom_icc_bcm_init(qp->bcms[i], dev);
212209

@@ -218,7 +215,7 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
218215
node = icc_node_create(qn->id);
219216
if (IS_ERR(node)) {
220217
ret = PTR_ERR(node);
221-
goto err;
218+
goto err_remove_nodes;
222219
}
223220

224221
node->name = qn->name;
@@ -232,19 +229,27 @@ int qcom_icc_rpmh_probe(struct platform_device *pdev)
232229
}
233230

234231
data->num_nodes = num_nodes;
232+
233+
ret = icc_provider_register(provider);
234+
if (ret)
235+
goto err_remove_nodes;
236+
235237
platform_set_drvdata(pdev, qp);
236238

237239
/* Populate child NoC devices if any */
238240
if (of_get_child_count(dev->of_node) > 0) {
239241
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
240242
if (ret)
241-
goto err;
243+
goto err_deregister_provider;
242244
}
243245

244246
return 0;
245-
err:
247+
248+
err_deregister_provider:
249+
icc_provider_deregister(provider);
250+
err_remove_nodes:
246251
icc_nodes_remove(provider);
247-
icc_provider_del(provider);
252+
248253
return ret;
249254
}
250255
EXPORT_SYMBOL_GPL(qcom_icc_rpmh_probe);
@@ -253,8 +258,8 @@ int qcom_icc_rpmh_remove(struct platform_device *pdev)
253258
{
254259
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
255260

261+
icc_provider_deregister(&qp->provider);
256262
icc_nodes_remove(&qp->provider);
257-
icc_provider_del(&qp->provider);
258263

259264
return 0;
260265
}

0 commit comments

Comments
 (0)