On 1.02.2023 11:15, Johan Hovold wrote: > 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: > > of_icc_xlate_onecell: invalid index 0 > cpu cpu0: error -EINVAL: error finding src node > cpu cpu0: dev_pm_opp_of_find_icc_paths: Unable to get path0: -22 > qcom-cpufreq-hw: probe of 18591000.cpufreq failed with error -22 > > Switch to using the new API where the provider is not registered until > after it has been fully initialised. > > Fixes: 5bc9900addaf ("interconnect: qcom: Add OSM L3 interconnect provider support") > Cc: stable@xxxxxxxxxxxxxxx # 5.7 > Signed-off-by: Johan Hovold <johan+linaro@xxxxxxxxxx> > --- Reviewed-by: Konrad Dybcio <konrad.dybcio@xxxxxxxxxx> Konrad > drivers/interconnect/qcom/osm-l3.c | 14 ++++++-------- > 1 file changed, 6 insertions(+), 8 deletions(-) > > diff --git a/drivers/interconnect/qcom/osm-l3.c b/drivers/interconnect/qcom/osm-l3.c > index 5fa171087425..3a1cbfe3e481 100644 > --- a/drivers/interconnect/qcom/osm-l3.c > +++ b/drivers/interconnect/qcom/osm-l3.c > @@ -158,8 +158,8 @@ static int qcom_osm_l3_remove(struct platform_device *pdev) > { > struct qcom_osm_l3_icc_provider *qp = platform_get_drvdata(pdev); > > + icc_provider_deregister(&qp->provider); > icc_nodes_remove(&qp->provider); > - icc_provider_del(&qp->provider); > > return 0; > } > @@ -245,14 +245,9 @@ static int qcom_osm_l3_probe(struct platform_device *pdev) > provider->set = qcom_osm_l3_set; > provider->aggregate = icc_std_aggregate; > provider->xlate = of_icc_xlate_onecell; > - INIT_LIST_HEAD(&provider->nodes); > provider->data = data; > > - ret = icc_provider_add(provider); > - if (ret) { > - dev_err(&pdev->dev, "error adding interconnect provider\n"); > - return ret; > - } > + icc_provider_init(provider); > > for (i = 0; i < num_nodes; i++) { > size_t j; > @@ -275,12 +270,15 @@ static int qcom_osm_l3_probe(struct platform_device *pdev) > } > data->num_nodes = num_nodes; > > + ret = icc_provider_register(provider); > + if (ret) > + goto err; > + > platform_set_drvdata(pdev, qp); > > return 0; > err: > icc_nodes_remove(provider); > - icc_provider_del(provider); > > return ret; > }