Commit 955bd9bb authored by Andrew Morton's avatar Andrew Morton Committed by Jeff Garzik

[PATCH] smc91x: power down PHY on suspend

From: Ian Campbell <icampbell@arcom.com>

Powering down the PHY saves something like 100mA at 5V on my platform.
Currently it is only done when the interface is brought down but it makes
sense to do it on suspend as well.
Signed-off-by: default avatarIan Campbell <icampbell@arcom.com>
Signed-off-by: default avatarNicolas Pitre <nico@cam.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 4ceb33e3
...@@ -1038,13 +1038,29 @@ static int smc_phy_reset(struct net_device *dev, int phy) ...@@ -1038,13 +1038,29 @@ static int smc_phy_reset(struct net_device *dev, int phy)
/* /*
* smc_phy_powerdown - powerdown phy * smc_phy_powerdown - powerdown phy
* @dev: net device * @dev: net device
* @phy: phy address
* *
* Power down the specified PHY * Power down the specified PHY
*/ */
static void smc_phy_powerdown(struct net_device *dev, int phy) static void smc_phy_powerdown(struct net_device *dev)
{ {
struct smc_local *lp = netdev_priv(dev);
unsigned int bmcr; unsigned int bmcr;
int phy = lp->mii.phy_id;
if (lp->phy_type == 0)
return;
/* We need to ensure that no calls to smc_phy_configure are
pending.
flush_scheduled_work() cannot be called because we are
running with the netlink semaphore held (from
devinet_ioctl()) and the pending work queue contains
linkwatch_event() (scheduled by netif_carrier_off()
above). linkwatch_event() also wants the netlink semaphore.
*/
while(lp->work_pending)
schedule();
bmcr = smc_phy_read(dev, phy, MII_BMCR); bmcr = smc_phy_read(dev, phy, MII_BMCR);
smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
...@@ -1583,21 +1599,7 @@ static int smc_close(struct net_device *dev) ...@@ -1583,21 +1599,7 @@ static int smc_close(struct net_device *dev)
/* clear everything */ /* clear everything */
smc_shutdown(dev); smc_shutdown(dev);
if (lp->phy_type != 0) { smc_phy_powerdown(dev);
/* We need to ensure that no calls to
smc_phy_configure are pending.
flush_scheduled_work() cannot be called because we
are running with the netlink semaphore held (from
devinet_ioctl()) and the pending work queue
contains linkwatch_event() (scheduled by
netif_carrier_off() above). linkwatch_event() also
wants the netlink semaphore.
*/
while(lp->work_pending)
schedule();
smc_phy_powerdown(dev, lp->mii.phy_id);
}
if (lp->pending_tx_skb) { if (lp->pending_tx_skb) {
dev_kfree_skb(lp->pending_tx_skb); dev_kfree_skb(lp->pending_tx_skb);
...@@ -2284,6 +2286,7 @@ static int smc_drv_suspend(struct device *dev, u32 state, u32 level) ...@@ -2284,6 +2286,7 @@ static int smc_drv_suspend(struct device *dev, u32 state, u32 level)
if (netif_running(ndev)) { if (netif_running(ndev)) {
netif_device_detach(ndev); netif_device_detach(ndev);
smc_shutdown(ndev); smc_shutdown(ndev);
smc_phy_powerdown(ndev);
} }
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment