diff options
| author | Daniel Mack <zonque@gmail.com> | 2014-05-24 03:34:26 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-05-29 18:23:29 -0400 |
| commit | 86f6cf41272de9d6ffa05ab46028b15d160a6f3e (patch) | |
| tree | 9dbea82327ba7dbd59d840da6ac29e2a13b92097 | |
| parent | 8f8382888cbaf6de13046437d41a1c3d1394d51f (diff) | |
net: of_mdio: add of_mdiobus_link_phydev()
Add a function to walk the list of subnodes of a mdio bus and look for
a node that matches the phy's address with its 'reg' property. If found,
set the of_node pointer for the phy. This allows auto-probed pyh
devices to be augmented by information passed in via DT.
Signed-off-by: Daniel Mack <zonque@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/phy/mdio_bus.c | 6 | ||||
| -rw-r--r-- | drivers/of/of_mdio.c | 33 | ||||
| -rw-r--r-- | include/linux/of_mdio.h | 8 |
3 files changed, 47 insertions, 0 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index a6284964b711..2e58aa54484c 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
| @@ -300,6 +300,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) | |||
| 300 | if (IS_ERR(phydev) || phydev == NULL) | 300 | if (IS_ERR(phydev) || phydev == NULL) |
| 301 | return phydev; | 301 | return phydev; |
| 302 | 302 | ||
| 303 | /* | ||
| 304 | * For DT, see if the auto-probed phy has a correspoding child | ||
| 305 | * in the bus node, and set the of_node pointer in this case. | ||
| 306 | */ | ||
| 307 | of_mdiobus_link_phydev(bus, phydev); | ||
| 308 | |||
| 303 | err = phy_device_register(phydev); | 309 | err = phy_device_register(phydev); |
| 304 | if (err) { | 310 | if (err) { |
| 305 | phy_device_free(phydev); | 311 | phy_device_free(phydev); |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 731d3d9052d7..7c8c142e4eb8 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
| @@ -183,6 +183,39 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
| 183 | } | 183 | } |
| 184 | EXPORT_SYMBOL(of_mdiobus_register); | 184 | EXPORT_SYMBOL(of_mdiobus_register); |
| 185 | 185 | ||
| 186 | /** | ||
| 187 | * of_mdiobus_link_phydev - Find a device node for a phy | ||
| 188 | * @mdio: pointer to mii_bus structure | ||
| 189 | * @phydev: phydev for which the of_node pointer should be set | ||
| 190 | * | ||
| 191 | * Walk the list of subnodes of a mdio bus and look for a node that matches the | ||
| 192 | * phy's address with its 'reg' property. If found, set the of_node pointer for | ||
| 193 | * the phy. This allows auto-probed pyh devices to be supplied with information | ||
| 194 | * passed in via DT. | ||
| 195 | */ | ||
| 196 | void of_mdiobus_link_phydev(struct mii_bus *mdio, | ||
| 197 | struct phy_device *phydev) | ||
| 198 | { | ||
| 199 | struct device *dev = &phydev->dev; | ||
| 200 | struct device_node *child; | ||
| 201 | |||
| 202 | if (dev->of_node || !mdio->dev.of_node) | ||
| 203 | return; | ||
| 204 | |||
| 205 | for_each_available_child_of_node(mdio->dev.of_node, child) { | ||
| 206 | int addr; | ||
| 207 | |||
| 208 | addr = of_mdio_parse_addr(&mdio->dev, child); | ||
| 209 | if (addr < 0) | ||
| 210 | continue; | ||
| 211 | |||
| 212 | if (addr == phydev->addr) { | ||
| 213 | dev->of_node = child; | ||
| 214 | return; | ||
| 215 | } | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 186 | /* Helper function for of_phy_find_device */ | 219 | /* Helper function for of_phy_find_device */ |
| 187 | static int of_phy_match(struct device *dev, void *phy_np) | 220 | static int of_phy_match(struct device *dev, void *phy_np) |
| 188 | { | 221 | { |
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h index d449018d0726..a70c9493d55a 100644 --- a/include/linux/of_mdio.h +++ b/include/linux/of_mdio.h | |||
| @@ -25,6 +25,9 @@ struct phy_device *of_phy_attach(struct net_device *dev, | |||
| 25 | 25 | ||
| 26 | extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np); | 26 | extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np); |
| 27 | 27 | ||
| 28 | extern void of_mdiobus_link_phydev(struct mii_bus *mdio, | ||
| 29 | struct phy_device *phydev); | ||
| 30 | |||
| 28 | #else /* CONFIG_OF */ | 31 | #else /* CONFIG_OF */ |
| 29 | static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | 32 | static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) |
| 30 | { | 33 | { |
| @@ -60,6 +63,11 @@ static inline struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np) | |||
| 60 | { | 63 | { |
| 61 | return NULL; | 64 | return NULL; |
| 62 | } | 65 | } |
| 66 | |||
| 67 | static inline void of_mdiobus_link_phydev(struct mii_bus *mdio, | ||
| 68 | struct phy_device *phydev) | ||
| 69 | { | ||
| 70 | } | ||
| 63 | #endif /* CONFIG_OF */ | 71 | #endif /* CONFIG_OF */ |
| 64 | 72 | ||
| 65 | #if defined(CONFIG_OF) && defined(CONFIG_FIXED_PHY) | 73 | #if defined(CONFIG_OF) && defined(CONFIG_FIXED_PHY) |
