aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2009-05-05 15:22:53 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-05 15:22:53 -0400
commitb6907b0c705b6db221f937b4d343e2a6b280c8c5 (patch)
tree1cc95afd264bc7ca29fb7ea4f1e32a35aff64fe8 /drivers/net
parentc7ae011dc8306d982c25fb4f679752e790a08dc4 (diff)
net: smsc911x: add power management functions
This adds a power management implementation for smsc911x.c which assumes the chips remains powered during suspend. The device is put in its D1 power saving mode. Signed-off-by: Daniel Mack <daniel@caiaq.de> Acked-by: Steve Glendinning <steve.glendinning@smsc.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/smsc911x.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 5113b26fc2d..9a8528c5bb5 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -2109,12 +2109,58 @@ out_0:
2109 return retval; 2109 return retval;
2110} 2110}
2111 2111
2112#ifdef CONFIG_PM
2113/* This implementation assumes the devices remains powered on its VDDVARIO
2114 * pins during suspend. */
2115
2116static int smsc911x_suspend(struct platform_device *pdev, pm_message_t state)
2117{
2118 struct net_device *dev = platform_get_drvdata(pdev);
2119 struct smsc911x_data *pdata = netdev_priv(dev);
2120
2121 /* enable wake on LAN, energy detection and the external PME
2122 * signal. */
2123 smsc911x_reg_write(pdata, PMT_CTRL,
2124 PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ |
2125 PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_);
2126
2127 return 0;
2128}
2129
2130static int smsc911x_resume(struct platform_device *pdev)
2131{
2132 struct net_device *dev = platform_get_drvdata(pdev);
2133 struct smsc911x_data *pdata = netdev_priv(dev);
2134 unsigned int to = 100;
2135
2136 /* Note 3.11 from the datasheet:
2137 * "When the LAN9220 is in a power saving state, a write of any
2138 * data to the BYTE_TEST register will wake-up the device."
2139 */
2140 smsc911x_reg_write(pdata, BYTE_TEST, 0);
2141
2142 /* poll the READY bit in PMT_CTRL. Any other access to the device is
2143 * forbidden while this bit isn't set. Try for 100ms and return -EIO
2144 * if it failed. */
2145 while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
2146 udelay(1000);
2147
2148 return (to == 0) ? -EIO : 0;
2149}
2150
2151#else
2152#define smsc911x_suspend NULL
2153#define smsc911x_resume NULL
2154#endif
2155
2112static struct platform_driver smsc911x_driver = { 2156static struct platform_driver smsc911x_driver = {
2113 .probe = smsc911x_drv_probe, 2157 .probe = smsc911x_drv_probe,
2114 .remove = smsc911x_drv_remove, 2158 .remove = smsc911x_drv_remove,
2115 .driver = { 2159 .driver = {
2116 .name = SMSC_CHIPNAME, 2160 .name = SMSC_CHIPNAME,
2117 }, 2161 },
2162 .suspend = smsc911x_suspend,
2163 .resume = smsc911x_resume,
2118}; 2164};
2119 2165
2120/* Entry point for loading the module */ 2166/* Entry point for loading the module */