[PATCH 07/12] net: mdio: make use of phy_device_atomic_register helper

From: Marco Felsch
Date: Wed Apr 05 2023 - 05:28:34 EST


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