Skip to content

Commit

Permalink
phy: power management support
Browse files Browse the repository at this point in the history
This patch adds the power management support into the physical
abstraction layer.

Suspend and resume functions respectively turns on/off the bit 11
into the PHY Basic mode control register.
Generic PHY device starts supporting PM.

In order to support the wake-on LAN and avoid to put in power down
the PHY device, the MDIO is aware of what the Ethernet device wants to do.

Voluntary, no CONFIG_PM defines were added into the sources.
Also generic suspend/resume functions are exported to allow
other drivers use them (such as genphy_config_aneg etc.).

Within the phy_driver_register function, we need to remove the
memset. It overrides the device driver owner and it is not good.

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Giuseppe Cavallaro authored and David S. Miller committed Nov 29, 2008
1 parent 914804b commit 0f0ca34
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
14 changes: 10 additions & 4 deletions drivers/net/phy/mdio_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,12 @@ 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_device *phydev = to_phy_device(dev);

if (drv && drv->suspend)
ret = drv->suspend(dev, state);
if ((!device_may_wakeup(phydev->dev.parent)) &&
(phydrv && phydrv->suspend))
ret = phydrv->suspend(phydev);

return ret;
}
Expand All @@ -295,9 +298,12 @@ 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_device *phydev = to_phy_device(dev);

if (drv && drv->resume)
ret = drv->resume(dev);
if ((!device_may_wakeup(phydev->dev.parent)) &&
(phydrv && phydrv->resume))
ret = phydrv->resume(phydev);

return ret;
}
Expand Down
31 changes: 30 additions & 1 deletion drivers/net/phy/phy_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,35 @@ static int genphy_config_init(struct phy_device *phydev)

return 0;
}
int genphy_suspend(struct phy_device *phydev)
{
int value;

mutex_lock(&phydev->lock);

value = phy_read(phydev, MII_BMCR);
phy_write(phydev, MII_BMCR, (value | BMCR_PDOWN));

mutex_unlock(&phydev->lock);

return 0;
}
EXPORT_SYMBOL(genphy_suspend);

int genphy_resume(struct phy_device *phydev)
{
int value;

mutex_lock(&phydev->lock);

value = phy_read(phydev, MII_BMCR);
phy_write(phydev, MII_BMCR, (value & ~BMCR_PDOWN));

mutex_unlock(&phydev->lock);

return 0;
}
EXPORT_SYMBOL(genphy_resume);

/**
* phy_probe - probe and init a PHY device
Expand Down Expand Up @@ -855,7 +883,6 @@ int phy_driver_register(struct phy_driver *new_driver)
{
int retval;

memset(&new_driver->driver, 0, sizeof(new_driver->driver));
new_driver->driver.name = new_driver->name;
new_driver->driver.bus = &mdio_bus_type;
new_driver->driver.probe = phy_probe;
Expand Down Expand Up @@ -890,6 +917,8 @@ static struct phy_driver genphy_driver = {
.features = 0,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.suspend = genphy_suspend,
.resume = genphy_resume,
.driver = {.owner= THIS_MODULE, },
};

Expand Down
2 changes: 2 additions & 0 deletions include/linux/phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,8 @@ int genphy_restart_aneg(struct phy_device *phydev);
int genphy_config_aneg(struct phy_device *phydev);
int genphy_update_link(struct phy_device *phydev);
int genphy_read_status(struct phy_device *phydev);
int genphy_suspend(struct phy_device *phydev);
int genphy_resume(struct phy_device *phydev);
void phy_driver_unregister(struct phy_driver *drv);
int phy_driver_register(struct phy_driver *new_driver);
void phy_prepare_link(struct phy_device *phydev,
Expand Down

0 comments on commit 0f0ca34

Please sign in to comment.