diff options
-rw-r--r-- | drivers/net/sky2.c | 54 |
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 | ||
4923 | static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | 4935 | static 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 |
4960 | static int sky2_resume(struct pci_dev *pdev) | 4965 | static 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 | |||
4994 | static 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 | ||
4999 | static void sky2_shutdown(struct pci_dev *pdev) | 5002 | static 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 | ||
5004 | static struct pci_driver sky2_driver = { | 5009 | static 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 | ||
5016 | static int __init sky2_init_module(void) | 5018 | static int __init sky2_init_module(void) |