diff options
Diffstat (limited to 'drivers/net/mdio/of_mdio.c')
-rw-r--r-- | drivers/net/mdio/of_mdio.c | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c index 64ebcb6d235c..08e607f62e10 100644 --- a/drivers/net/mdio/of_mdio.c +++ b/drivers/net/mdio/of_mdio.c @@ -139,6 +139,53 @@ bool of_mdiobus_child_is_phy(struct device_node *child) } EXPORT_SYMBOL(of_mdiobus_child_is_phy); +static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np, + bool *scanphys) +{ + struct device_node *child; + int addr, rc = 0; + + /* Loop over the child nodes and register a phy_device for each phy */ + for_each_available_child_of_node(np, child) { + if (of_node_name_eq(child, "ethernet-phy-package")) { + /* Ignore invalid ethernet-phy-package node */ + if (!of_property_present(child, "reg")) + continue; + + rc = __of_mdiobus_parse_phys(mdio, child, NULL); + if (rc && rc != -ENODEV) + goto exit; + + continue; + } + + addr = of_mdio_parse_addr(&mdio->dev, child); + if (addr < 0) { + /* Skip scanning for invalid ethernet-phy-package node */ + if (scanphys) + *scanphys = true; + 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); + + if (rc == -ENODEV) + dev_err(&mdio->dev, + "MDIO device at address %d is missing.\n", + addr); + else if (rc) + goto exit; + } + + return 0; +exit: + of_node_put(child); + return rc; +} + /** * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure @@ -180,33 +227,18 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, return rc; /* Loop over the child nodes and register a phy_device for each phy */ - for_each_available_child_of_node(np, child) { - addr = of_mdio_parse_addr(&mdio->dev, child); - if (addr < 0) { - scanphys = true; - 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); - - if (rc == -ENODEV) - dev_err(&mdio->dev, - "MDIO device at address %d is missing.\n", - addr); - else if (rc) - goto unregister; - } + rc = __of_mdiobus_parse_phys(mdio, np, &scanphys); + if (rc) + goto unregister; if (!scanphys) return 0; /* auto scan for PHYs with empty reg property */ for_each_available_child_of_node(np, child) { - /* Skip PHYs with reg property set */ - if (of_property_present(child, "reg")) + /* Skip PHYs with reg property set or ethernet-phy-package node */ + if (of_property_present(child, "reg") || + of_node_name_eq(child, "ethernet-phy-package")) continue; for (addr = 0; addr < PHY_MAX_ADDR; addr++) { @@ -227,15 +259,16 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, if (!rc) break; if (rc != -ENODEV) - goto unregister; + goto put_unregister; } } } return 0; -unregister: +put_unregister: of_node_put(child); +unregister: mdiobus_unregister(mdio); return rc; } |