diff options
author | David S. Miller <davem@davemloft.net> | 2014-05-29 18:23:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-29 18:23:49 -0400 |
commit | c3aad35e4890d79084ab70c54a5d7740045d2f90 (patch) | |
tree | 00ef5d250678eca0ae539dca4a10d2d6de5334d9 | |
parent | 6623b4194459c07859d3e3196c3994fa7be5b88e (diff) | |
parent | 24f28dde5bed3b6322003dca903ebf7732efa550 (diff) |
Merge branch 'of_mdio'
Daniel Mack says:
====================
mdio: Parse DT nodes for auto-probed PHYs
Here's v2.
v1 -> v2:
* Switch to of_property_read_u32() in patch #1
* Check for mdio->dev_of_node in patch #2
* Added Florian's Reviewed-by: tags
====================
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 | 72 | ||||
-rw-r--r-- | include/linux/of_mdio.h | 8 |
3 files changed, 72 insertions, 14 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 7c6e277cdd1f..2fe922bfade8 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -88,6 +88,27 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi | |||
88 | return 0; | 88 | return 0; |
89 | } | 89 | } |
90 | 90 | ||
91 | static int of_mdio_parse_addr(struct device *dev, const struct device_node *np) | ||
92 | { | ||
93 | u32 addr; | ||
94 | int ret; | ||
95 | |||
96 | ret = of_property_read_u32(np, "reg", &addr); | ||
97 | if (ret < 0) { | ||
98 | dev_err(dev, "%s has invalid PHY address\n", np->full_name); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* A PHY must have a reg property in the range [0-31] */ | ||
103 | if (addr >= PHY_MAX_ADDR) { | ||
104 | dev_err(dev, "%s PHY address %i is too large\n", | ||
105 | np->full_name, addr); | ||
106 | return -EINVAL; | ||
107 | } | ||
108 | |||
109 | return addr; | ||
110 | } | ||
111 | |||
91 | /** | 112 | /** |
92 | * of_mdiobus_register - Register mii_bus and create PHYs from the device tree | 113 | * of_mdiobus_register - Register mii_bus and create PHYs from the device tree |
93 | * @mdio: pointer to mii_bus structure | 114 | * @mdio: pointer to mii_bus structure |
@@ -102,7 +123,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
102 | const __be32 *paddr; | 123 | const __be32 *paddr; |
103 | u32 addr; | 124 | u32 addr; |
104 | bool scanphys = false; | 125 | bool scanphys = false; |
105 | int rc, i, len; | 126 | int rc, i; |
106 | 127 | ||
107 | /* Mask out all PHYs from auto probing. Instead the PHYs listed in | 128 | /* Mask out all PHYs from auto probing. Instead the PHYs listed in |
108 | * the device tree are populated after the bus has been registered */ | 129 | * the device tree are populated after the bus has been registered */ |
@@ -122,19 +143,9 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
122 | 143 | ||
123 | /* Loop over the child nodes and register a phy_device for each one */ | 144 | /* Loop over the child nodes and register a phy_device for each one */ |
124 | for_each_available_child_of_node(np, child) { | 145 | for_each_available_child_of_node(np, child) { |
125 | /* A PHY must have a reg property in the range [0-31] */ | 146 | addr = of_mdio_parse_addr(&mdio->dev, child); |
126 | paddr = of_get_property(child, "reg", &len); | 147 | if (addr < 0) { |
127 | if (!paddr || len < sizeof(*paddr)) { | ||
128 | scanphys = true; | 148 | scanphys = true; |
129 | dev_err(&mdio->dev, "%s has invalid PHY address\n", | ||
130 | child->full_name); | ||
131 | continue; | ||
132 | } | ||
133 | |||
134 | addr = be32_to_cpup(paddr); | ||
135 | if (addr >= PHY_MAX_ADDR) { | ||
136 | dev_err(&mdio->dev, "%s PHY address %i is too large\n", | ||
137 | child->full_name, addr); | ||
138 | continue; | 149 | continue; |
139 | } | 150 | } |
140 | 151 | ||
@@ -149,7 +160,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
149 | /* auto scan for PHYs with empty reg property */ | 160 | /* auto scan for PHYs with empty reg property */ |
150 | for_each_available_child_of_node(np, child) { | 161 | for_each_available_child_of_node(np, child) { |
151 | /* Skip PHYs with reg property set */ | 162 | /* Skip PHYs with reg property set */ |
152 | paddr = of_get_property(child, "reg", &len); | 163 | paddr = of_get_property(child, "reg", NULL); |
153 | if (paddr) | 164 | if (paddr) |
154 | continue; | 165 | continue; |
155 | 166 | ||
@@ -172,6 +183,39 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) | |||
172 | } | 183 | } |
173 | EXPORT_SYMBOL(of_mdiobus_register); | 184 | EXPORT_SYMBOL(of_mdiobus_register); |
174 | 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 | |||
175 | /* Helper function for of_phy_find_device */ | 219 | /* Helper function for of_phy_find_device */ |
176 | static int of_phy_match(struct device *dev, void *phy_np) | 220 | static int of_phy_match(struct device *dev, void *phy_np) |
177 | { | 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) |