diff options
Diffstat (limited to 'drivers/net/phy/phy_device.c')
-rw-r--r-- | drivers/net/phy/phy_device.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index db1172db1e7c..19ab8a7d1e48 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -93,7 +93,12 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) | |||
93 | if (!netdev) | 93 | if (!netdev) |
94 | return !phydev->suspended; | 94 | return !phydev->suspended; |
95 | 95 | ||
96 | /* Don't suspend PHY if the attached netdev parent may wakeup. | 96 | if (netdev->wol_enabled) |
97 | return false; | ||
98 | |||
99 | /* As long as not all affected network drivers support the | ||
100 | * wol_enabled flag, let's check for hints that WoL is enabled. | ||
101 | * Don't suspend PHY if the attached netdev parent may wake up. | ||
97 | * The parent may point to a PCI device, as in tg3 driver. | 102 | * The parent may point to a PCI device, as in tg3 driver. |
98 | */ | 103 | */ |
99 | if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent)) | 104 | if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent)) |
@@ -1132,9 +1137,9 @@ void phy_detach(struct phy_device *phydev) | |||
1132 | sysfs_remove_link(&dev->dev.kobj, "phydev"); | 1137 | sysfs_remove_link(&dev->dev.kobj, "phydev"); |
1133 | sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev"); | 1138 | sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev"); |
1134 | } | 1139 | } |
1140 | phy_suspend(phydev); | ||
1135 | phydev->attached_dev->phydev = NULL; | 1141 | phydev->attached_dev->phydev = NULL; |
1136 | phydev->attached_dev = NULL; | 1142 | phydev->attached_dev = NULL; |
1137 | phy_suspend(phydev); | ||
1138 | phydev->phylink = NULL; | 1143 | phydev->phylink = NULL; |
1139 | 1144 | ||
1140 | phy_led_triggers_unregister(phydev); | 1145 | phy_led_triggers_unregister(phydev); |
@@ -1168,12 +1173,13 @@ EXPORT_SYMBOL(phy_detach); | |||
1168 | int phy_suspend(struct phy_device *phydev) | 1173 | int phy_suspend(struct phy_device *phydev) |
1169 | { | 1174 | { |
1170 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); | 1175 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
1176 | struct net_device *netdev = phydev->attached_dev; | ||
1171 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; | 1177 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; |
1172 | int ret = 0; | 1178 | int ret = 0; |
1173 | 1179 | ||
1174 | /* If the device has WOL enabled, we cannot suspend the PHY */ | 1180 | /* If the device has WOL enabled, we cannot suspend the PHY */ |
1175 | phy_ethtool_get_wol(phydev, &wol); | 1181 | phy_ethtool_get_wol(phydev, &wol); |
1176 | if (wol.wolopts) | 1182 | if (wol.wolopts || (netdev && netdev->wol_enabled)) |
1177 | return -EBUSY; | 1183 | return -EBUSY; |
1178 | 1184 | ||
1179 | if (phydev->drv && phydrv->suspend) | 1185 | if (phydev->drv && phydrv->suspend) |