Commit 9fbd3552 authored by Johan Hovold's avatar Johan Hovold Committed by Georgi Djakov
Browse files

interconnect: imx: 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: f0d80485 ("interconnect: Add imx core driver")
Cc: stable@vger.kernel.org      # 5.8
Cc: Alexandre Bailon <abailon@baylibre.com>
Reviewed-by: default avatarKonrad Dybcio <konrad.dybcio@linaro.org>
Signed-off-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com> # i.MX8MP MSC SM2-MB-EP1 Board
Link: https://lore.kernel.org/r/20230306075651.2449-5-johan+linaro@kernel.org


Signed-off-by: default avatarGeorgi Djakov <djakov@kernel.org>
parent eb59eca0
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -295,6 +295,9 @@ int imx_icc_register(struct platform_device *pdev,
	provider->xlate = of_icc_xlate_onecell;
	provider->data = data;
	provider->dev = dev->parent;

	icc_provider_init(provider);

	platform_set_drvdata(pdev, imx_provider);

	if (settings) {
@@ -306,20 +309,18 @@ int imx_icc_register(struct platform_device *pdev,
		}
	}

	ret = icc_provider_add(provider);
	if (ret) {
		dev_err(dev, "error adding interconnect provider: %d\n", ret);
	ret = imx_icc_register_nodes(imx_provider, nodes, nodes_count, settings);
	if (ret)
		return ret;
	}

	ret = imx_icc_register_nodes(imx_provider, nodes, nodes_count, settings);
	ret = icc_provider_register(provider);
	if (ret)
		goto provider_del;
		goto err_unregister_nodes;

	return 0;

provider_del:
	icc_provider_del(provider);
err_unregister_nodes:
	imx_icc_unregister_nodes(&imx_provider->provider);
	return ret;
}
EXPORT_SYMBOL_GPL(imx_icc_register);
@@ -328,9 +329,8 @@ void imx_icc_unregister(struct platform_device *pdev)
{
	struct imx_icc_provider *imx_provider = platform_get_drvdata(pdev);

	icc_provider_deregister(&imx_provider->provider);
	imx_icc_unregister_nodes(&imx_provider->provider);

	icc_provider_del(&imx_provider->provider);
}
EXPORT_SYMBOL_GPL(imx_icc_unregister);