[PATCH net-next v4 2/4] net: mdio: factor out OF child registration helpers

From: James Hilliard

Date: Thu Aug 06 2026 - 23:55:29 EST


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 <james.hilliard1@xxxxxxxxx>

---
Changes v1 -> v2:
- split from the ACx00 series without code changes
---
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