Skip to contentSkip to conversation

mdio: Parse DT nodes for auto-probed PHYs

PATCH In review Daniel Mack 2 participants 5 messages May 24, 2014 – May 29, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v2 cover mdio: Parse DT nodes for auto-probed PHYs

Hi Florian,

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

Thanks!
Daniel

Daniel Mack (3):
net: of_mdio: factor out code to parse a phy's 'reg' property
net: of_mdio: add of_mdiobus_link_phydev()
net: of_mdio: don't store the length of a property if we don't need to

 drivers/net/phy/mdio_bus.c |  6 ++++
 drivers/of/of_mdio.c       | 72 +++++++++++++++++++++++++++++++++++++---------
 include/linux/of_mdio.h    |  8 ++++++
 3 files changed, 72 insertions(+), 14 deletions(-)
Signature · 1 line
1.9.0
#1 lore raw

PATCH v2 1/3 net: of_mdio: factor out code to parse a phy's 'reg' property

Factor out some logic into of_mdio_parse_addr() so it can be reused later. While at it, use of_property_read_u32() rather than open-coding the same logic again.

---
 drivers/of/of_mdio.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)
drivers/of/of_mdio.c +23 -12
index 9a95831..4eb335e 100644
@@ -114,6 +114,27 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi
 	return 0;
 }
 
+static int of_mdio_parse_addr(struct device *dev, const struct device_node *np)
+{
+	u32 addr;
+	int ret;
+
+	ret = of_property_read_u32(np, "reg", &addr);
+	if (ret < 0) {
+		dev_err(dev, "%s has invalid PHY address\n", np->full_name);
+		return ret;
+	}
+
+	/* A PHY must have a reg property in the range [0-31] */
+	if (addr >= PHY_MAX_ADDR) {
+		dev_err(dev, "%s PHY address %i is too large\n",
+			np->full_name, addr);
+		return -EINVAL;
+	}
+
+	return addr;
+}
+
 /**
  * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
  * @mdio: pointer to mii_bus structure
@@ -148,19 +169,9 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 
 	/* Loop over the child nodes and register a phy_device for each one */
 	for_each_available_child_of_node(np, child) {
-		/* A PHY must have a reg property in the range [0-31] */
-		paddr = of_get_property(child, "reg", &len);
-		if (!paddr || len < sizeof(*paddr)) {
+		addr = of_mdio_parse_addr(&mdio->dev, child);
+		if (addr < 0) {
 			scanphys = true;
-			dev_err(&mdio->dev, "%s has invalid PHY address\n",
-				child->full_name);
-			continue;
-		}
-
-		addr = be32_to_cpup(paddr);
-		if (addr >= PHY_MAX_ADDR) {
-			dev_err(&mdio->dev, "%s PHY address %i is too large\n",
-				child->full_name, addr);
 			continue;
 		}
 
Signature · 1 line
1.9.0
#2 lore raw

PATCH v2 2/3 net: of_mdio: add of_mdiobus_link_phydev()

In reply to Daniel Mack

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.

---
 drivers/net/phy/mdio_bus.c |  6 ++++++
 drivers/of/of_mdio.c       | 33 +++++++++++++++++++++++++++++++++
 include/linux/of_mdio.h    |  8 ++++++++
 3 files changed, 47 insertions(+)
drivers/net/phy/mdio_bus.c +6 -0
index 76f54b3..e1444b2 100644
@@ -233,6 +233,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
 	if (IS_ERR(phydev) || phydev == NULL)
 		return phydev;
 
+	/*
+	 * For DT, see if the auto-probed phy has a correspoding child
+	 * in the bus node, and set the of_node pointer in this case.
+	 */
+	of_mdiobus_link_phydev(bus, phydev);
+
 	err = phy_device_register(phydev);
 	if (err) {
 		phy_device_free(phydev);
drivers/of/of_mdio.c +33 -0
index 4eb335e..92e09ac 100644
@@ -209,6 +209,39 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 }
 EXPORT_SYMBOL(of_mdiobus_register);
 
+/**
+ * of_mdiobus_link_phydev - Find a device node for a phy
+ * @mdio: pointer to mii_bus structure
+ * @phydev: phydev for which the of_node pointer should be set
+ *
+ * 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 supplied with information
+ * passed in via DT.
+ */
+void of_mdiobus_link_phydev(struct mii_bus *mdio,
+			    struct phy_device *phydev)
+{
+	struct device *dev = &phydev->dev;
+	struct device_node *child;
+
+	if (dev->of_node || !mdio->dev.of_node)
+		return;
+
+	for_each_available_child_of_node(mdio->dev.of_node, child) {
+		int addr;
+
+		addr = of_mdio_parse_addr(&mdio->dev, child);
+		if (addr < 0)
+			continue;
+
+		if (addr == phydev->addr) {
+			dev->of_node = child;
+			return;
+		}
+	}
+}
+
 /* Helper function for of_phy_find_device */
 static int of_phy_match(struct device *dev, void *phy_np)
 {
include/linux/of_mdio.h +8 -0
index 881a7c3..de72206 100644
@@ -28,6 +28,9 @@ extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
 
 extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
 
+extern void of_mdiobus_link_phydev(struct mii_bus *mdio,
+				   struct phy_device *phydev);
+
 #else /* CONFIG_OF */
 static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 {
@@ -70,6 +73,11 @@ static inline struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np)
 {
 	return NULL;
 }
+
+static inline void of_mdiobus_link_phydev(struct mii_bus *mdio,
+					  struct phy_device *phydev)
+{
+}
 #endif /* CONFIG_OF */
 
 #endif /* __LINUX_OF_MDIO_H */
Signature · 1 line
1.9.0
#3 lore raw

PATCH v2 3/3 net: of_mdio: don't store the length of a property if we don't need to

In reply to Daniel Mack

of_get_property() can be called with NULL as 2nd argument if the caller is not interested in the length of a property. Use that here so we can get rid of a variable.

---
 drivers/of/of_mdio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/of/of_mdio.c +2 -2
index 92e09ac..c719601 100644
@@ -149,7 +149,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 	const __be32 *paddr;
 	u32 addr;
 	bool scanphys = false;
-	int rc, i, len;
+	int rc, i;
 
 	/* Mask out all PHYs from auto probing.  Instead the PHYs listed in
 	 * the device tree are populated after the bus has been registered */
@@ -186,7 +186,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 	/* auto scan for PHYs with empty reg property */
 	for_each_available_child_of_node(np, child) {
 		/* Skip PHYs with reg property set */
-		paddr = of_get_property(child, "reg", &len);
+		paddr = of_get_property(child, "reg", NULL);
 		if (paddr)
 			continue;
 
Signature · 1 line
1.9.0
maintainer
#4 lore raw
In reply to Daniel Mack

From: Daniel Mack <[email protected]>
Date: Sat, 24 May 2014 09:34:24 +0200

Quoted 6 lines

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

Series applied to net-next, thank you.