The current fwnode_mdiobus_register_phy() implementation assume that the phy is accessible to read the PHYID register values first which isn't the case in some cases. Fix this by using the new phy_device_atomic_register() helper which ensures that the prerequisites are fulfilled before accessing the PHYID registers. Signed-off-by: Marco Felsch <m.felsch@xxxxxxxxxxxxxx> --- Documentation/firmware-guide/acpi/dsd/phy.rst | 2 +- drivers/net/mdio/acpi_mdio.c | 18 ++++++++++++------ drivers/net/mdio/of_mdio.c | 13 ++++++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/Documentation/firmware-guide/acpi/dsd/phy.rst b/Documentation/firmware-guide/acpi/dsd/phy.rst index 673ac374f92a..489e978c7412 100644 --- a/Documentation/firmware-guide/acpi/dsd/phy.rst +++ b/Documentation/firmware-guide/acpi/dsd/phy.rst @@ -5,7 +5,7 @@ MDIO bus and PHYs in ACPI ========================= The PHYs on an MDIO bus [phy] are probed and registered using -fwnode_mdiobus_register_phy(). +phy_device_atomic_register(). Later, for connecting these PHYs to their respective MACs, the PHYs registered on the MDIO bus have to be referenced. diff --git a/drivers/net/mdio/acpi_mdio.c b/drivers/net/mdio/acpi_mdio.c index 4630dde01974..25feb571bd1f 100644 --- a/drivers/net/mdio/acpi_mdio.c +++ b/drivers/net/mdio/acpi_mdio.c @@ -31,8 +31,10 @@ MODULE_LICENSE("GPL"); int __acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode, struct module *owner) { + struct phy_device_config config = { + .mii_bus = mdio, + }; struct fwnode_handle *child; - u32 addr; int ret; /* Mask out all PHYs from auto probing. */ @@ -45,15 +47,19 @@ int __acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode, /* Loop over the child nodes and register a phy_device for each PHY */ fwnode_for_each_child_node(fwnode, child) { - ret = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), &addr); - if (ret || addr >= PHY_MAX_ADDR) + struct phy_device *phy; + + ret = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), + &config.phy_addr); + if (ret || config.phy_addr >= PHY_MAX_ADDR) continue; - ret = fwnode_mdiobus_register_phy(mdio, child, addr); - if (ret == -ENODEV) + config.fwnode = child; + phy = phy_device_atomic_register(&config); + if (PTR_ERR(phy) == -ENODEV) dev_err(&mdio->dev, "MDIO device at address %d is missing.\n", - addr); + config.phy_addr); } return 0; } diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c index 7eb32ebb846d..10dd45c3bde0 100644 --- a/drivers/net/mdio/of_mdio.c +++ b/drivers/net/mdio/of_mdio.c @@ -45,7 +45,18 @@ EXPORT_SYMBOL(of_mdiobus_phy_device_register); static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *child, u32 addr) { - return fwnode_mdiobus_register_phy(mdio, of_fwnode_handle(child), addr); + struct phy_device_config config = { + .mii_bus = mdio, + .phy_addr = addr, + .fwnode = of_fwnode_handle(child), + }; + struct phy_device *phy; + + phy = phy_device_atomic_register(&config); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + return 0; } static int of_mdiobus_register_device(struct mii_bus *mdio, -- 2.39.2