Commit eb6779d4 authored by Vaibhav Gupta's avatar Vaibhav Gupta Committed by Jeff Kirsher

e1000: use generic power management

With legacy PM hooks, it was the responsibility of a driver to manage PCI
states and also the device's power state. The generic approach is to let PCI
core handle the work.

e1000_suspend() calls __e1000_shutdown() to perform intermediate tasks.
__e1000_shutdown() modifies the value of "wake" (device should be wakeup
enabled or not), responsible for controlling the flow of legacy PM.

Since, PCI core has no idea about the value of "wake", new code for generic
PM may produce unexpected results. Thus, use "device_set_wakeup_enable()"
to wakeup-enable the device accordingly.
Signed-off-by: default avatarVaibhav Gupta <vaibhavgupta40@gmail.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 6bf6be11
...@@ -151,10 +151,8 @@ static int e1000_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -151,10 +151,8 @@ static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
__be16 proto, u16 vid); __be16 proto, u16 vid);
static void e1000_restore_vlan(struct e1000_adapter *adapter); static void e1000_restore_vlan(struct e1000_adapter *adapter);
#ifdef CONFIG_PM static int __maybe_unused e1000_suspend(struct device *dev);
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); static int __maybe_unused e1000_resume(struct device *dev);
static int e1000_resume(struct pci_dev *pdev);
#endif
static void e1000_shutdown(struct pci_dev *pdev); static void e1000_shutdown(struct pci_dev *pdev);
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
...@@ -179,16 +177,16 @@ static const struct pci_error_handlers e1000_err_handler = { ...@@ -179,16 +177,16 @@ static const struct pci_error_handlers e1000_err_handler = {
.resume = e1000_io_resume, .resume = e1000_io_resume,
}; };
static SIMPLE_DEV_PM_OPS(e1000_pm_ops, e1000_suspend, e1000_resume);
static struct pci_driver e1000_driver = { static struct pci_driver e1000_driver = {
.name = e1000_driver_name, .name = e1000_driver_name,
.id_table = e1000_pci_tbl, .id_table = e1000_pci_tbl,
.probe = e1000_probe, .probe = e1000_probe,
.remove = e1000_remove, .remove = e1000_remove,
#ifdef CONFIG_PM .driver = {
/* Power Management Hooks */ .pm = &e1000_pm_ops,
.suspend = e1000_suspend, },
.resume = e1000_resume,
#endif
.shutdown = e1000_shutdown, .shutdown = e1000_shutdown,
.err_handler = &e1000_err_handler .err_handler = &e1000_err_handler
}; };
...@@ -5060,9 +5058,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) ...@@ -5060,9 +5058,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 ctrl, ctrl_ext, rctl, status; u32 ctrl, ctrl_ext, rctl, status;
u32 wufc = adapter->wol; u32 wufc = adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
#endif
netif_device_detach(netdev); netif_device_detach(netdev);
...@@ -5076,12 +5071,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) ...@@ -5076,12 +5071,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
e1000_down(adapter); e1000_down(adapter);
} }
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
if (retval)
return retval;
#endif
status = er32(STATUS); status = er32(STATUS);
if (status & E1000_STATUS_LU) if (status & E1000_STATUS_LU)
wufc &= ~E1000_WUFC_LNKC; wufc &= ~E1000_WUFC_LNKC;
...@@ -5142,37 +5131,26 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake) ...@@ -5142,37 +5131,26 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
return 0; return 0;
} }
#ifdef CONFIG_PM static int __maybe_unused e1000_suspend(struct device *dev)
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
{ {
int retval; int retval;
struct pci_dev *pdev = to_pci_dev(dev);
bool wake; bool wake;
retval = __e1000_shutdown(pdev, &wake); retval = __e1000_shutdown(pdev, &wake);
if (retval) device_set_wakeup_enable(dev, wake);
return retval;
if (wake) {
pci_prepare_to_sleep(pdev);
} else {
pci_wake_from_d3(pdev, false);
pci_set_power_state(pdev, PCI_D3hot);
}
return 0; return retval;
} }
static int e1000_resume(struct pci_dev *pdev) static int __maybe_unused e1000_resume(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u32 err; u32 err;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_save_state(pdev);
if (adapter->need_ioport) if (adapter->need_ioport)
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
else else
...@@ -5209,7 +5187,6 @@ static int e1000_resume(struct pci_dev *pdev) ...@@ -5209,7 +5187,6 @@ static int e1000_resume(struct pci_dev *pdev)
return 0; return 0;
} }
#endif
static void e1000_shutdown(struct pci_dev *pdev) static void e1000_shutdown(struct pci_dev *pdev)
{ {
......
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