aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-05-29 18:23:49 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-29 18:23:49 -0400
commitc3aad35e4890d79084ab70c54a5d7740045d2f90 (patch)
tree00ef5d250678eca0ae539dca4a10d2d6de5334d9
parent6623b4194459c07859d3e3196c3994fa7be5b88e (diff)
parent24f28dde5bed3b6322003dca903ebf7732efa550 (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.c6
-rw-r--r--drivers/of/of_mdio.c72
-rw-r--r--include/linux/of_mdio.h8
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
91static 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}
173EXPORT_SYMBOL(of_mdiobus_register); 184EXPORT_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 */
196void 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 */
176static int of_phy_match(struct device *dev, void *phy_np) 220static 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
26extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np); 26extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
27 27
28extern void of_mdiobus_link_phydev(struct mii_bus *mdio,
29 struct phy_device *phydev);
30
28#else /* CONFIG_OF */ 31#else /* CONFIG_OF */
29static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) 32static 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
67static 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)