[PATCH] net: fec: Defer probe if other FEC has deferred MDIO

From: A. Sverdlin
Date: Wed Feb 08 2023 - 05:19:45 EST


From: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxxxx>

In FEC_QUIRK_SINGLE_MDIO case, if fec1 has mdio subnode which is being
probe-deferred because of, for instance, reset-gpio, defer any consequtive
fec2+ probe, we don't want them to register DT-less MDIO bus, but to share
DT-aware MDIO bus from fec1.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxxxx>
---
drivers/net/ethernet/freescale/fec_main.c | 34 +++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 2341597408d12..d4d6dc10dba71 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2301,14 +2301,13 @@ static int fec_enet_mii_init(struct platform_device *pdev)
* mdio interface in board design, and need to be configured by
* fec0 mii_bus.
*/
- if ((fep->quirks & FEC_QUIRK_SINGLE_MDIO) && fep->dev_id > 0) {
+ if (fep->quirks & FEC_QUIRK_SINGLE_MDIO) {
/* fec1 uses fec0 mii_bus */
if (mii_cnt && fec0_mii_bus) {
fep->mii_bus = fec0_mii_bus;
mii_cnt++;
return 0;
}
- return -ENOENT;
}

bus_freq = 2500000; /* 2.5MHz by default */
@@ -2319,6 +2318,37 @@ static int fec_enet_mii_init(struct platform_device *pdev)
"suppress-preamble");
}

+ while (!node) {
+ /* If we've got so far there is either no FEC node with mdio
+ * subnode at all (in this case original behavior was to go on
+ * and create an MDIO bus not related to any DT node), or there
+ * is another FEC node with mdio subnode out there (in this case
+ * we defer the probe until MDIO bus will be instantiated in the
+ * context of its parent node.
+ */
+ struct device_node *np, *cp;
+ const struct of_device_id *of_id = of_match_device(fec_dt_ids, &pdev->dev);
+
+ if (!of_id)
+ break;
+
+ /* Loop over nodes with same "compatible" as pdev has */
+ for_each_compatible_node(np, NULL, of_id->compatible) {
+ if (!of_device_is_available(np))
+ continue;
+
+ cp = of_get_child_by_name(np, "mdio");
+ if (cp) {
+ of_node_put(cp);
+ of_node_put(np);
+
+ return -EPROBE_DEFER;
+ }
+ }
+
+ break;
+ }
+
/*
* Set MII speed (= clk_get_rate() / 2 * phy_speed)
*
--
2.34.1