{
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
+       bool enable_wakeup = false;
+       int i;
 
        if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) ||
            !device_can_wakeup(&hw->pdev->dev))
                return -EOPNOTSUPP;
 
        sky2->wol = wol->wolopts;
+
+       for (i = 0; i < hw->ports; i++) {
+               struct net_device *dev = hw->dev[i];
+               struct sky2_port *sky2 = netdev_priv(dev);
+
+               if (sky2->wol)
+                       enable_wakeup = true;
+       }
+       device_set_wakeup_enable(&hw->pdev->dev, enable_wakeup);
+
        return 0;
 }
 
        pci_set_drvdata(pdev, NULL);
 }
 
-static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
+static int sky2_suspend(struct device *dev)
 {
+       struct pci_dev *pdev = to_pci_dev(dev);
        struct sky2_hw *hw = pci_get_drvdata(pdev);
-       int i, wol = 0;
+       int i;
 
        if (!hw)
                return 0;
 
                if (sky2->wol)
                        sky2_wol_init(sky2);
-
-               wol |= sky2->wol;
        }
 
-       device_set_wakeup_enable(&pdev->dev, wol != 0);
-
        sky2_power_aux(hw);
        rtnl_unlock();
 
-       pci_save_state(pdev);
-       pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
        return 0;
 }
 
 #ifdef CONFIG_PM
-static int sky2_resume(struct pci_dev *pdev)
+static int sky2_resume(struct device *dev)
 {
+       struct pci_dev *pdev = to_pci_dev(dev);
        struct sky2_hw *hw = pci_get_drvdata(pdev);
        int err;
 
        if (!hw)
                return 0;
 
-       err = pci_set_power_state(pdev, PCI_D0);
-       if (err)
-               goto out;
-
-       err = pci_restore_state(pdev);
-       if (err)
-               goto out;
-
-       pci_enable_wake(pdev, PCI_D0, 0);
-
        /* Re-enable all clocks */
        err = pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
        if (err) {
        pci_disable_device(pdev);
        return err;
 }
+
+static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);
+#define SKY2_PM_OPS (&sky2_pm_ops)
+
+#else
+
+#define SKY2_PM_OPS NULL
 #endif
 
 static void sky2_shutdown(struct pci_dev *pdev)
 {
-       sky2_suspend(pdev, PMSG_SUSPEND);
+       sky2_suspend(&pdev->dev);
+       pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
+       pci_set_power_state(pdev, PCI_D3hot);
 }
 
 static struct pci_driver sky2_driver = {
        .id_table = sky2_id_table,
        .probe = sky2_probe,
        .remove = __devexit_p(sky2_remove),
-#ifdef CONFIG_PM
-       .suspend = sky2_suspend,
-       .resume = sky2_resume,
-#endif
        .shutdown = sky2_shutdown,
+       .driver.pm = SKY2_PM_OPS,
 };
 
 static int __init sky2_init_module(void)