diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2014-05-21 09:29:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-22 15:43:02 -0400 |
commit | de906af1cf8d5f2e9c461148577ac26dcdaea86e (patch) | |
tree | 4732496e85bf6845316ea9055605abf4b20dbda1 /drivers/net/phy | |
parent | c242a47238fa2a6a54af8a16e62b54e6e031d4bc (diff) |
net: phy: make of_set_phy_supported work with genphy driver
of_set_phy_supported allows overwiting hardware capabilities of
a phy with values from the devicetree. of_set_phy_supported is
called right after phy_device_register in the assumption that
phy_probe is called from phy_device_register and the features
of the phy are already initialized. For the genphy driver this
is not true, here phy_probe is called later during phy_connect
time. phy_probe will then overwrite all settings done from
of_set_phy_supported
Fix this by moving of_set_phy_supported to the core phy code
and calling it from phy_probe.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/phy_device.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index fc569eae7215..eb3b946bd8c0 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/mdio.h> | 33 | #include <linux/mdio.h> |
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
36 | #include <linux/of.h> | ||
36 | 37 | ||
37 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
38 | 39 | ||
@@ -1166,6 +1167,38 @@ static int gen10g_resume(struct phy_device *phydev) | |||
1166 | return 0; | 1167 | return 0; |
1167 | } | 1168 | } |
1168 | 1169 | ||
1170 | static void of_set_phy_supported(struct phy_device *phydev) | ||
1171 | { | ||
1172 | struct device_node *node = phydev->dev.of_node; | ||
1173 | u32 max_speed; | ||
1174 | |||
1175 | if (!IS_ENABLED(CONFIG_OF_MDIO)) | ||
1176 | return; | ||
1177 | |||
1178 | if (!node) | ||
1179 | return; | ||
1180 | |||
1181 | if (!of_property_read_u32(node, "max-speed", &max_speed)) { | ||
1182 | /* The default values for phydev->supported are provided by the PHY | ||
1183 | * driver "features" member, we want to reset to sane defaults fist | ||
1184 | * before supporting higher speeds. | ||
1185 | */ | ||
1186 | phydev->supported &= PHY_DEFAULT_FEATURES; | ||
1187 | |||
1188 | switch (max_speed) { | ||
1189 | default: | ||
1190 | return; | ||
1191 | |||
1192 | case SPEED_1000: | ||
1193 | phydev->supported |= PHY_1000BT_FEATURES; | ||
1194 | case SPEED_100: | ||
1195 | phydev->supported |= PHY_100BT_FEATURES; | ||
1196 | case SPEED_10: | ||
1197 | phydev->supported |= PHY_10BT_FEATURES; | ||
1198 | } | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1169 | /** | 1202 | /** |
1170 | * phy_probe - probe and init a PHY device | 1203 | * phy_probe - probe and init a PHY device |
1171 | * @dev: device to probe and init | 1204 | * @dev: device to probe and init |
@@ -1200,7 +1233,8 @@ static int phy_probe(struct device *dev) | |||
1200 | * or both of these values | 1233 | * or both of these values |
1201 | */ | 1234 | */ |
1202 | phydev->supported = phydrv->features; | 1235 | phydev->supported = phydrv->features; |
1203 | phydev->advertising = phydrv->features; | 1236 | of_set_phy_supported(phydev); |
1237 | phydev->advertising = phydev->supported; | ||
1204 | 1238 | ||
1205 | /* Set the state to READY by default */ | 1239 | /* Set the state to READY by default */ |
1206 | phydev->state = PHY_READY; | 1240 | phydev->state = PHY_READY; |