Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: mdiobus: search for PSE nodes by parsing PHY nodes.

Some PHYs can be linked with PSE (Power Sourcing Equipment), so search
for related nodes and attach it to the phydev.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Oleksij Rempel and committed by
Jakub Kicinski
5e82147d cfaa202a

+39 -2
+35 -2
drivers/net/mdio/fwnode_mdio.c
··· 10 10 #include <linux/fwnode_mdio.h> 11 11 #include <linux/of.h> 12 12 #include <linux/phy.h> 13 + #include <linux/pse-pd/pse.h> 13 14 14 15 MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>"); 15 16 MODULE_LICENSE("GPL"); 17 + 18 + static struct pse_control * 19 + fwnode_find_pse_control(struct fwnode_handle *fwnode) 20 + { 21 + struct pse_control *psec; 22 + struct device_node *np; 23 + 24 + if (!IS_ENABLED(CONFIG_PSE_CONTROLLER)) 25 + return NULL; 26 + 27 + np = to_of_node(fwnode); 28 + if (!np) 29 + return NULL; 30 + 31 + psec = of_pse_control_get(np); 32 + if (PTR_ERR(psec) == -ENOENT) 33 + return NULL; 34 + 35 + return psec; 36 + } 16 37 17 38 static struct mii_timestamper * 18 39 fwnode_find_mii_timestamper(struct fwnode_handle *fwnode) ··· 112 91 struct fwnode_handle *child, u32 addr) 113 92 { 114 93 struct mii_timestamper *mii_ts = NULL; 94 + struct pse_control *psec = NULL; 115 95 struct phy_device *phy; 116 96 bool is_c45 = false; 117 97 u32 phy_id; 118 98 int rc; 119 99 100 + psec = fwnode_find_pse_control(child); 101 + if (IS_ERR(psec)) 102 + return PTR_ERR(psec); 103 + 120 104 mii_ts = fwnode_find_mii_timestamper(child); 121 - if (IS_ERR(mii_ts)) 122 - return PTR_ERR(mii_ts); 105 + if (IS_ERR(mii_ts)) { 106 + rc = PTR_ERR(mii_ts); 107 + goto clean_pse; 108 + } 123 109 124 110 rc = fwnode_property_match_string(child, "compatible", 125 111 "ethernet-phy-ieee802.3-c45"); ··· 162 134 goto clean_phy; 163 135 } 164 136 137 + phy->psec = psec; 138 + 165 139 /* phy->mii_ts may already be defined by the PHY driver. A 166 140 * mii_timestamper probed via the device tree will still have 167 141 * precedence. 168 142 */ 169 143 if (mii_ts) 170 144 phy->mii_ts = mii_ts; 145 + 171 146 return 0; 172 147 173 148 clean_phy: 174 149 phy_device_free(phy); 175 150 clean_mii_ts: 176 151 unregister_mii_timestamper(mii_ts); 152 + clean_pse: 153 + pse_control_put(psec); 177 154 178 155 return rc; 179 156 }
+2
drivers/net/phy/phy_device.c
··· 26 26 #include <linux/netdevice.h> 27 27 #include <linux/phy.h> 28 28 #include <linux/phy_led_triggers.h> 29 + #include <linux/pse-pd/pse.h> 29 30 #include <linux/property.h> 30 31 #include <linux/sfp.h> 31 32 #include <linux/skbuff.h> ··· 992 991 void phy_device_remove(struct phy_device *phydev) 993 992 { 994 993 unregister_mii_timestamper(phydev->mii_ts); 994 + pse_control_put(phydev->psec); 995 995 996 996 device_del(&phydev->mdio.dev); 997 997
+2
include/linux/phy.h
··· 597 597 * @master_slave_get: Current master/slave advertisement 598 598 * @master_slave_state: Current master/slave configuration 599 599 * @mii_ts: Pointer to time stamper callbacks 600 + * @psec: Pointer to Power Sourcing Equipment control struct 600 601 * @lock: Mutex for serialization access to PHY 601 602 * @state_queue: Work queue for state machine 602 603 * @shared: Pointer to private data shared by phys in one package ··· 716 715 struct phylink *phylink; 717 716 struct net_device *attached_dev; 718 717 struct mii_timestamper *mii_ts; 718 + struct pse_control *psec; 719 719 720 720 u8 mdix; 721 721 u8 mdix_ctrl;