From f0043f61f8825299670992e4ff0d7bdf8cce88e1 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 1 Feb 2009 00:53:34 -0800 Subject: [PATCH] --- yaml --- r: 133938 b: refs/heads/master c: 3d1e4db2b0698785f4e4dd139d88257e855e53b8 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/net/phy/mdio_bus.c | 54 +++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index fad6f89b9349..69b8e8af9202 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2884e5cc9283d541977bdf5dc344849af94cd639 +refs/heads/master: 3d1e4db2b0698785f4e4dd139d88257e855e53b8 diff --git a/trunk/drivers/net/phy/mdio_bus.c b/trunk/drivers/net/phy/mdio_bus.c index 811a637695ca..bb29ae3ff17d 100644 --- a/trunk/drivers/net/phy/mdio_bus.c +++ b/trunk/drivers/net/phy/mdio_bus.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -286,33 +287,58 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) (phydev->phy_id & phydrv->phy_id_mask)); } +static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) +{ + struct device_driver *drv = phydev->dev.driver; + struct phy_driver *phydrv = to_phy_driver(drv); + struct net_device *netdev = phydev->attached_dev; + + if (!drv || !phydrv->suspend) + return false; + + /* PHY not attached? May suspend. */ + if (!netdev) + return true; + + /* + * Don't suspend PHY if the attched netdev parent may wakeup. + * The parent may point to a PCI device, as in tg3 driver. + */ + if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent)) + return false; + + /* + * Also don't suspend PHY if the netdev itself may wakeup. This + * is the case for devices w/o underlaying pwr. mgmt. aware bus, + * e.g. SoC devices. + */ + if (device_may_wakeup(&netdev->dev)) + return false; + + return true; +} + /* Suspend and resume. Copied from platform_suspend and * platform_resume */ static int mdio_bus_suspend(struct device * dev, pm_message_t state) { - int ret = 0; - struct device_driver *drv = dev->driver; - struct phy_driver *phydrv = to_phy_driver(drv); + struct phy_driver *phydrv = to_phy_driver(dev->driver); struct phy_device *phydev = to_phy_device(dev); - if (drv && phydrv->suspend && !device_may_wakeup(phydev->dev.parent)) - ret = phydrv->suspend(phydev); - - return ret; + if (!mdio_bus_phy_may_suspend(phydev)) + return 0; + return phydrv->suspend(phydev); } static int mdio_bus_resume(struct device * dev) { - int ret = 0; - struct device_driver *drv = dev->driver; - struct phy_driver *phydrv = to_phy_driver(drv); + struct phy_driver *phydrv = to_phy_driver(dev->driver); struct phy_device *phydev = to_phy_device(dev); - if (drv && phydrv->resume && !device_may_wakeup(phydev->dev.parent)) - ret = phydrv->resume(phydev); - - return ret; + if (!mdio_bus_phy_may_suspend(phydev)) + return 0; + return phydrv->resume(phydev); } struct bus_type mdio_bus_type = {