[PATCH] net: fec: manage corner deferred probe condition

From: Pierluigi Passaro
Date: Sun Jan 15 2023 - 12:49:31 EST


For dual fec interfaces, external phys can only be configured by fec0.
When the function of_mdiobus_register return -EPROBE_DEFER, the driver
is lately called to manage fec1, which wrongly register its mii_bus as
fec0_mii_bus.
When fec0 retry the probe, the previous assignement prevent the MDIO bus
registration.
Use a static boolean to trace the orginal MDIO bus deferred probe and
prevent further registrations until the fec0 registration completed
succesfully.

Signed-off-by: Pierluigi Passaro <pierluigi.p@xxxxxxxxxxxxx>
---
drivers/net/ethernet/freescale/fec_main.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 644f3c963730..b4ca3bd4283f 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2284,6 +2284,18 @@ static int fec_enet_mii_init(struct platform_device *pdev)
int err = -ENXIO;
u32 mii_speed, holdtime;
u32 bus_freq;
+ static bool wait_for_mdio_bus = false;
+
+ bus_freq = 2500000; /* 2.5MHz by default */
+ node = of_get_child_by_name(pdev->dev.of_node, "mdio");
+ if (node) {
+ wait_for_mdio_bus = false;
+ of_property_read_u32(node, "clock-frequency", &bus_freq);
+ suppress_preamble = of_property_read_bool(node,
+ "suppress-preamble");
+ }
+ if (wait_for_mdio_bus)
+ return -EPROBE_DEFER;

/*
* The i.MX28 dual fec interfaces are not equal.
@@ -2311,14 +2323,6 @@ static int fec_enet_mii_init(struct platform_device *pdev)
return -ENOENT;
}

- bus_freq = 2500000; /* 2.5MHz by default */
- node = of_get_child_by_name(pdev->dev.of_node, "mdio");
- if (node) {
- of_property_read_u32(node, "clock-frequency", &bus_freq);
- suppress_preamble = of_property_read_bool(node,
- "suppress-preamble");
- }
-
/*
* Set MII speed (= clk_get_rate() / 2 * phy_speed)
*
@@ -2389,6 +2393,8 @@ static int fec_enet_mii_init(struct platform_device *pdev)
fep->mii_bus->parent = &pdev->dev;

err = of_mdiobus_register(fep->mii_bus, node);
+ if (err == -EPROBE_DEFER)
+ wait_for_mdio_bus = true;
if (err)
goto err_out_free_mdiobus;
of_node_put(node);
--
2.37.2