diff options
author | Lucas Stach <dev@lynxeye.de> | 2022-01-16 22:32:20 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-01-18 08:31:14 +0100 |
commit | 67b79e90a09e7134ee0225d97ec0dcb7ebcf861b (patch) | |
tree | 54c5f6d8f9563a2caf5b0fc9c4b3d3b0e5dd5279 /drivers/soc/imx/gpcv2.c | |
parent | e69f764faf0dfcaaef725676b980b4d6d77605eb (diff) | |
download | barebox-67b79e90a09e7134ee0225d97ec0dcb7ebcf861b.tar.gz barebox-67b79e90a09e7134ee0225d97ec0dcb7ebcf861b.tar.xz |
soc: imx: gpcv2: split PGC domain probe in two passes
Currently it is possible that the platform device for a nested PGC
domain is added before the parent PGC device is there, which leads to
-EPROBE_DEFER when probing the driver. With normal probe this isn't
an issue, as the probe will be retried. With deep-probe this is fatal,
as the PGC domain devices aren't probed from DT, but via registration
of platform devices from the GPC driver, so the usual deep-probe
approach to ensure the devices are probed before the lookup isn't
working in this case.
Make sure to register the PGC domain platform devices in the correct
order to avoid the EPROBE_DEFER altogether.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
Link: https://lore.barebox.org/20220116213221.3466936-2-dev@lynxeye.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/soc/imx/gpcv2.c')
-rw-r--r-- | drivers/soc/imx/gpcv2.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index 565c86cb02..62cfc21519 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -429,7 +429,7 @@ static int imx_gpcv2_probe(struct device_d *dev) struct device_node *pgc_np, *np; struct resource *res; void __iomem *base; - int ret; + int ret, pass = 0; pgc_np = of_get_child_by_name(dev->device_node, "pgc"); if (!pgc_np) { @@ -445,10 +445,23 @@ static int imx_gpcv2_probe(struct device_d *dev) domain_data = of_device_get_match_data(dev); + /* + * Run two passes for the registration of the PGC domain platform + * devices: first all devices that are not part of a power-domain + * themselves, then all the others. This avoids -EPROBE_DEFER being + * returned for nested domains, that need their parent PGC domains + * to be present on probe. + */ +again: for_each_child_of_node(pgc_np, np) { - struct device_d *pd_dev; + bool child_domain = of_property_read_bool(np, "power-domains"); struct imx_pgc_domain *domain; + struct device_d *pd_dev; u32 domain_index; + + if ((pass == 0 && child_domain) || (pass == 1 && !child_domain)) + continue; + ret = of_property_read_u32(np, "reg", &domain_index); if (ret) { dev_err(dev, "Failed to read 'reg' property\n"); @@ -481,6 +494,11 @@ static int imx_gpcv2_probe(struct device_d *dev) return ret; } + if (pass == 0) { + pass++; + goto again; + } + return 0; } |