[PATCH 2/3] soc: imx: gpcv2: split PGC domain probe in two passes

Lucas Stach dev at lynxeye.de
Sun Jan 16 13:32:20 PST 2022


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 at lynxeye.de>
---
 drivers/soc/imx/gpcv2.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index bc373ecf40cc..8abeb15d0378 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;
 }
 
-- 
2.31.1




More information about the barebox mailing list