aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/sky2.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index d6577084ce70..0d4a236c3bb3 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3398,12 +3398,24 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
3398{ 3398{
3399 struct sky2_port *sky2 = netdev_priv(dev); 3399 struct sky2_port *sky2 = netdev_priv(dev);
3400 struct sky2_hw *hw = sky2->hw; 3400 struct sky2_hw *hw = sky2->hw;
3401 bool enable_wakeup = false;
3402 int i;
3401 3403
3402 if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) || 3404 if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
3403 !device_can_wakeup(&hw->pdev->dev)) 3405 !device_can_wakeup(&hw->pdev->dev))
3404 return -EOPNOTSUPP; 3406 return -EOPNOTSUPP;
3405 3407
3406 sky2->wol = wol->wolopts; 3408 sky2->wol = wol->wolopts;
3409
3410 for (i = 0; i < hw->ports; i++) {
3411 struct net_device *dev = hw->dev[i];
3412 struct sky2_port *sky2 = netdev_priv(dev);
3413
3414 if (sky2->wol)
3415 enable_wakeup = true;
3416 }
3417 device_set_wakeup_enable(&hw->pdev->dev, enable_wakeup);
3418
3407 return 0; 3419 return 0;
3408} 3420}
3409 3421
@@ -4920,10 +4932,11 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
4920 pci_set_drvdata(pdev, NULL); 4932 pci_set_drvdata(pdev, NULL);
4921} 4933}
4922 4934
4923static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) 4935static int sky2_suspend(struct device *dev)
4924{ 4936{
4937 struct pci_dev *pdev = to_pci_dev(dev);
4925 struct sky2_hw *hw = pci_get_drvdata(pdev); 4938 struct sky2_hw *hw = pci_get_drvdata(pdev);
4926 int i, wol = 0; 4939 int i;
4927 4940
4928 if (!hw) 4941 if (!hw)
4929 return 0; 4942 return 0;
@@ -4940,41 +4953,24 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
4940 4953
4941 if (sky2->wol) 4954 if (sky2->wol)
4942 sky2_wol_init(sky2); 4955 sky2_wol_init(sky2);
4943
4944 wol |= sky2->wol;
4945 } 4956 }
4946 4957
4947 device_set_wakeup_enable(&pdev->dev, wol != 0);
4948
4949 sky2_power_aux(hw); 4958 sky2_power_aux(hw);
4950 rtnl_unlock(); 4959 rtnl_unlock();
4951 4960
4952 pci_save_state(pdev);
4953 pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
4954 pci_set_power_state(pdev, pci_choose_state(pdev, state));
4955
4956 return 0; 4961 return 0;
4957} 4962}
4958 4963
4959#ifdef CONFIG_PM 4964#ifdef CONFIG_PM
4960static int sky2_resume(struct pci_dev *pdev) 4965static int sky2_resume(struct device *dev)
4961{ 4966{
4967 struct pci_dev *pdev = to_pci_dev(dev);
4962 struct sky2_hw *hw = pci_get_drvdata(pdev); 4968 struct sky2_hw *hw = pci_get_drvdata(pdev);
4963 int err; 4969 int err;
4964 4970
4965 if (!hw) 4971 if (!hw)
4966 return 0; 4972 return 0;
4967 4973
4968 err = pci_set_power_state(pdev, PCI_D0);
4969 if (err)
4970 goto out;
4971
4972 err = pci_restore_state(pdev);
4973 if (err)
4974 goto out;
4975
4976 pci_enable_wake(pdev, PCI_D0, 0);
4977
4978 /* Re-enable all clocks */ 4974 /* Re-enable all clocks */
4979 err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0); 4975 err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
4980 if (err) { 4976 if (err) {
@@ -4994,11 +4990,20 @@ out:
4994 pci_disable_device(pdev); 4990 pci_disable_device(pdev);
4995 return err; 4991 return err;
4996} 4992}
4993
4994static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);
4995#define SKY2_PM_OPS (&sky2_pm_ops)
4996
4997#else
4998
4999#define SKY2_PM_OPS NULL
4997#endif 5000#endif
4998 5001
4999static void sky2_shutdown(struct pci_dev *pdev) 5002static void sky2_shutdown(struct pci_dev *pdev)
5000{ 5003{
5001 sky2_suspend(pdev, PMSG_SUSPEND); 5004 sky2_suspend(&pdev->dev);
5005 pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
5006 pci_set_power_state(pdev, PCI_D3hot);
5002} 5007}
5003 5008
5004static struct pci_driver sky2_driver = { 5009static struct pci_driver sky2_driver = {
@@ -5006,11 +5011,8 @@ static struct pci_driver sky2_driver = {
5006 .id_table = sky2_id_table, 5011 .id_table = sky2_id_table,
5007 .probe = sky2_probe, 5012 .probe = sky2_probe,
5008 .remove = __devexit_p(sky2_remove), 5013 .remove = __devexit_p(sky2_remove),
5009#ifdef CONFIG_PM
5010 .suspend = sky2_suspend,
5011 .resume = sky2_resume,
5012#endif
5013 .shutdown = sky2_shutdown, 5014 .shutdown = sky2_shutdown,
5015 .driver.pm = SKY2_PM_OPS,
5014}; 5016};
5015 5017
5016static int __init sky2_init_module(void) 5018static int __init sky2_init_module(void)