aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/efx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r--drivers/net/sfc/efx.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 14ef27fa8416..b016719d8f67 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -2243,11 +2243,107 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
2243 return rc; 2243 return rc;
2244} 2244}
2245 2245
2246static int efx_pm_freeze(struct device *dev)
2247{
2248 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
2249
2250 efx->state = STATE_FINI;
2251
2252 netif_device_detach(efx->net_dev);
2253
2254 efx_stop_all(efx);
2255 efx_fini_channels(efx);
2256
2257 return 0;
2258}
2259
2260static int efx_pm_thaw(struct device *dev)
2261{
2262 struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
2263
2264 efx->state = STATE_INIT;
2265
2266 efx_init_channels(efx);
2267
2268 mutex_lock(&efx->mac_lock);
2269 efx->phy_op->reconfigure(efx);
2270 mutex_unlock(&efx->mac_lock);
2271
2272 efx_start_all(efx);
2273
2274 netif_device_attach(efx->net_dev);
2275
2276 efx->state = STATE_RUNNING;
2277
2278 efx->type->resume_wol(efx);
2279
2280 return 0;
2281}
2282
2283static int efx_pm_poweroff(struct device *dev)
2284{
2285 struct pci_dev *pci_dev = to_pci_dev(dev);
2286 struct efx_nic *efx = pci_get_drvdata(pci_dev);
2287
2288 efx->type->fini(efx);
2289
2290 efx->reset_pending = RESET_TYPE_NONE;
2291
2292 pci_save_state(pci_dev);
2293 return pci_set_power_state(pci_dev, PCI_D3hot);
2294}
2295
2296/* Used for both resume and restore */
2297static int efx_pm_resume(struct device *dev)
2298{
2299 struct pci_dev *pci_dev = to_pci_dev(dev);
2300 struct efx_nic *efx = pci_get_drvdata(pci_dev);
2301 int rc;
2302
2303 rc = pci_set_power_state(pci_dev, PCI_D0);
2304 if (rc)
2305 return rc;
2306 pci_restore_state(pci_dev);
2307 rc = pci_enable_device(pci_dev);
2308 if (rc)
2309 return rc;
2310 pci_set_master(efx->pci_dev);
2311 rc = efx->type->reset(efx, RESET_TYPE_ALL);
2312 if (rc)
2313 return rc;
2314 rc = efx->type->init(efx);
2315 if (rc)
2316 return rc;
2317 efx_pm_thaw(dev);
2318 return 0;
2319}
2320
2321static int efx_pm_suspend(struct device *dev)
2322{
2323 int rc;
2324
2325 efx_pm_freeze(dev);
2326 rc = efx_pm_poweroff(dev);
2327 if (rc)
2328 efx_pm_resume(dev);
2329 return rc;
2330}
2331
2332static struct dev_pm_ops efx_pm_ops = {
2333 .suspend = efx_pm_suspend,
2334 .resume = efx_pm_resume,
2335 .freeze = efx_pm_freeze,
2336 .thaw = efx_pm_thaw,
2337 .poweroff = efx_pm_poweroff,
2338 .restore = efx_pm_resume,
2339};
2340
2246static struct pci_driver efx_pci_driver = { 2341static struct pci_driver efx_pci_driver = {
2247 .name = EFX_DRIVER_NAME, 2342 .name = EFX_DRIVER_NAME,
2248 .id_table = efx_pci_table, 2343 .id_table = efx_pci_table,
2249 .probe = efx_pci_probe, 2344 .probe = efx_pci_probe,
2250 .remove = efx_pci_remove, 2345 .remove = efx_pci_remove,
2346 .driver.pm = &efx_pm_ops,
2251}; 2347};
2252 2348
2253/************************************************************************** 2349/**************************************************************************