[PATCH 04/21] net: mdio: factor out OF child registration helpers
From: James Hilliard <hidden>
Date: 2026-08-03 05:15:59
Also in:
linux-arm-kernel, linux-devicetree, linux-rockchip, linux-sunxi, lkml
Subsystem:
ethernet phy library, networking drivers, the rest · Maintainers:
Andrew Lunn, Heiner Kallweit, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Live OF reconfiguration needs to create the same PHY and generic MDIO devices as initial bus population, including legacy PHY nodes that need address scanning. Factor fixed-address child registration and PHY address scanning into helpers. The old scan loop also visited every free address for a child without a reg property even when the child was not a PHY. Reject that case before scanning while preserving enumeration of valid PHY and generic MDIO children. Signed-off-by: James Hilliard <redacted> --- drivers/net/mdio/of_mdio.c | 66 ++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 26 deletions(-)
diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c
index b8d298c04d3f..051e449bbe7c 100644
--- a/drivers/net/mdio/of_mdio.c
+++ b/drivers/net/mdio/of_mdio.c@@ -77,6 +77,15 @@ static int of_mdiobus_register_device(struct mii_bus *mdio, return 0; } +static int of_mdiobus_register_child(struct mii_bus *mdio, + struct device_node *child, u32 addr) +{ + if (of_mdiobus_child_is_phy(child)) + return of_mdiobus_register_phy(mdio, child, addr); + + return of_mdiobus_register_device(mdio, child, addr); +} + /* The following is a list of PHY compatible strings which appear in * some DTBs. The compatible string is never matched against a PHY * driver, so is pointless. We only expect devices which are not PHYs
@@ -136,6 +145,32 @@ bool of_mdiobus_child_is_phy(struct device_node *child) } EXPORT_SYMBOL(of_mdiobus_child_is_phy); +static int of_mdiobus_scan_phy(struct mii_bus *mdio, + struct device_node *child) +{ + int addr, rc; + + if (!of_mdiobus_child_is_phy(child)) + return -ENODEV; + + for (addr = 0; addr < PHY_MAX_ADDR; addr++) { + if (mdiobus_is_registered_device(mdio, addr)) + continue; + + dev_info(&mdio->dev, "scan phy %pOFn at address %i\n", + child, addr); + + /* -ENODEV means that scanning should continue. */ + rc = of_mdiobus_register_child(mdio, child, addr); + if (!rc) + return 0; + if (rc != -ENODEV) + return rc; + } + + return -ENODEV; +} + static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np, bool *scanphys) {
@@ -164,10 +199,7 @@ static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np, continue; } - if (of_mdiobus_child_is_phy(child)) - rc = of_mdiobus_register_phy(mdio, child, addr); - else - rc = of_mdiobus_register_device(mdio, child, addr); + rc = of_mdiobus_register_child(mdio, child, addr); if (rc == -ENODEV) dev_err(&mdio->dev,
@@ -197,7 +229,7 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, { struct device_node *child; bool scanphys = false; - int addr, rc; + int rc; if (!np) return __mdiobus_register(mdio, owner);
@@ -238,27 +270,9 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, of_node_name_eq(child, "ethernet-phy-package")) continue; - for (addr = 0; addr < PHY_MAX_ADDR; addr++) { - /* skip already registered PHYs */ - if (mdiobus_is_registered_device(mdio, addr)) - continue; - - /* be noisy to encourage people to set reg property */ - dev_info(&mdio->dev, "scan phy %pOFn at address %i\n", - child, addr); - - if (of_mdiobus_child_is_phy(child)) { - /* -ENODEV is the return code that PHYLIB has - * standardized on to indicate that bus - * scanning should continue. - */ - rc = of_mdiobus_register_phy(mdio, child, addr); - if (!rc) - break; - if (rc != -ENODEV) - goto put_unregister; - } - } + rc = of_mdiobus_scan_phy(mdio, child); + if (rc && rc != -ENODEV) + goto put_unregister; } return 0;
--
2.53.0