1 The 2.6.29 kernel has new struct dev_pm_ops [1] which are used
2 on the pci device to distinguish power management hooks for suspend
3 to RAM and hibernation. Older kernels don't have these so we need
4 to resort back to the good ol' suspend/resume. Fortunately the calls
5 are not so different so it should be possible to resuse the same
6 calls on compat code with only slight modifications.
8 [1] http://lxr.linux.no/#linux+v2.6.29/include/linux/pm.h#L170
10 --- a/drivers/net/wireless/ath/ath5k/base.c
11 +++ b/drivers/net/wireless/ath/ath5k/base.c
12 @@ -197,6 +197,33 @@ static void __devexit ath5k_pci_remove(s
14 static int ath5k_pci_suspend(struct device *dev);
15 static int ath5k_pci_resume(struct device *dev);
16 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
17 +static int ath5k_pci_suspend_compat(struct pci_dev *pdev, pm_message_t state)
21 + r = ath5k_pci_suspend(&pdev->dev);
25 + pci_save_state(pdev);
26 + pci_disable_device(pdev);
27 + pci_set_power_state(pdev, PCI_D3hot);
31 +static int ath5k_pci_resume_compat(struct pci_dev *pdev)
35 + pci_restore_state(pdev);
36 + r = pci_enable_device(pdev);
40 + return ath5k_pci_resume(&pdev->dev);
44 SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
45 #define ATH5K_PM_OPS (&ath5k_pm_ops)
46 @@ -209,7 +236,12 @@ static struct pci_driver ath5k_pci_drive
47 .id_table = ath5k_pci_id_table,
48 .probe = ath5k_pci_probe,
49 .remove = __devexit_p(ath5k_pci_remove),
50 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
51 .driver.pm = ATH5K_PM_OPS,
52 +#elif defined(CONFIG_PM)
53 + .suspend = ath5k_pci_suspend_compat,
54 + .resume = ath5k_pci_resume_compat,