Skip to content

Commit 90ae93d

Browse files
jhovoldGeorgi Djakov
authored andcommitted
interconnect: qcom: rpm: 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: 62feb14 ("interconnect: qcom: Consolidate interconnect RPM support") Fixes: 30c8fa3 ("interconnect: qcom: Add MSM8916 interconnect provider driver") Cc: [email protected] # 5.7 Reviewed-by: Konrad Dybcio <[email protected]> Reviewed-by: Jun Nie <[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 bc46320 commit 90ae93d

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

drivers/interconnect/qcom/icc-rpm.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -503,28 +503,22 @@ int qnoc_probe(struct platform_device *pdev)
503503
}
504504

505505
provider = &qp->provider;
506-
INIT_LIST_HEAD(&provider->nodes);
507506
provider->dev = dev;
508507
provider->set = qcom_icc_set;
509508
provider->pre_aggregate = qcom_icc_pre_bw_aggregate;
510509
provider->aggregate = qcom_icc_bw_aggregate;
511510
provider->xlate_extended = qcom_icc_xlate_extended;
512511
provider->data = data;
513512

514-
ret = icc_provider_add(provider);
515-
if (ret) {
516-
dev_err(dev, "error adding interconnect provider: %d\n", ret);
517-
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
518-
return ret;
519-
}
513+
icc_provider_init(provider);
520514

521515
for (i = 0; i < num_nodes; i++) {
522516
size_t j;
523517

524518
node = icc_node_create(qnodes[i]->id);
525519
if (IS_ERR(node)) {
526520
ret = PTR_ERR(node);
527-
goto err;
521+
goto err_remove_nodes;
528522
}
529523

530524
node->name = qnodes[i]->name;
@@ -538,20 +532,26 @@ int qnoc_probe(struct platform_device *pdev)
538532
}
539533
data->num_nodes = num_nodes;
540534

535+
ret = icc_provider_register(provider);
536+
if (ret)
537+
goto err_remove_nodes;
538+
541539
platform_set_drvdata(pdev, qp);
542540

543541
/* Populate child NoC devices if any */
544542
if (of_get_child_count(dev->of_node) > 0) {
545543
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
546544
if (ret)
547-
goto err;
545+
goto err_deregister_provider;
548546
}
549547

550548
return 0;
551-
err:
549+
550+
err_deregister_provider:
551+
icc_provider_deregister(provider);
552+
err_remove_nodes:
552553
icc_nodes_remove(provider);
553554
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
554-
icc_provider_del(provider);
555555

556556
return ret;
557557
}
@@ -561,9 +561,9 @@ int qnoc_remove(struct platform_device *pdev)
561561
{
562562
struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
563563

564+
icc_provider_deregister(&qp->provider);
564565
icc_nodes_remove(&qp->provider);
565566
clk_bulk_disable_unprepare(qp->num_clks, qp->bus_clks);
566-
icc_provider_del(&qp->provider);
567567

568568
return 0;
569569
}

0 commit comments

Comments
 (0)