commit b42f2ce8d11fe30cd4a3bf6a0ab76766d3214ec6 Author: Johannes Berg Date: Thu Aug 2 10:03:24 2012 +0200 [RFC] compat: handle pci suspend/resume on kernel 2.6.29 Before kernel 2.6.29, we use compat_pci_{suspend,resume} and not the SIMPLE_DEV_PM_OPS, which include the code for PCI device handling. For 2.6.30 and higher, the core PCI code includes the device handling. That leaves 2.6.29 as the odd one out and causes suspend and resume to fail. Fix it by including the PCI device handling code in the definition of SIMPLE_DEV_PM_OPS for that kernel version. Change-Id: I21e5ad6b4d810469c19fd642867b8caa58ed5072 Signed-off-by: Johannes Berg diff --git a/include/linux/compat-2.6.32.h b/include/linux/compat-2.6.32.h index b0c699a..04ea50f 100644 --- a/include/linux/compat-2.6.32.h +++ b/include/linux/compat-2.6.32.h @@ -116,9 +116,45 @@ typedef enum netdev_tx netdev_tx_t; /* * dev_pm_ops is only available on kernels >= 2.6.29, for * older kernels we rely on reverting the work to old - * power management style stuff. + * power management style stuff. On 2.6.29 the pci calls + * weren't included yet though, so include them here. */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,29)) +#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ +struct dev_pm_ops name; \ +static int __compat_suspend_fn_ ## name(struct device *dev) \ +{ \ + int ret = suspend_fn(dev); \ + if (ret) \ + return ret; \ + if (dev->bus == &pci_bus_type) { \ + pci_save_state(to_pci_dev(dev)); \ + pci_disable_device(to_pci_dev(dev)); \ + pci_set_power_state(to_pci_dev(dev), PCI_D3hot);\ + } \ + return 0; \ +} \ +static int __compat_resume_fn_ ## name(struct device *dev) \ +{ \ + int ret; \ + if (dev->bus == &pci_bus_type) { \ + pci_set_power_state(to_pci_dev(dev), PCI_D0); \ + ret = pci_enable_device(to_pci_dev(dev)); \ + if (ret) \ + return ret; \ + pci_restore_state(to_pci_dev(dev)); \ + } \ + return resume_fn(dev); \ +} \ +typeof(name) name = { \ + .suspend = __compat_suspend_fn_ ## name, \ + .resume = __compat_resume_fn_ ## name, \ + .freeze = __compat_suspend_fn_ ## name, \ + .thaw = __compat_resume_fn_ ## name, \ + .poweroff = __compat_suspend_fn_ ## name, \ + .restore = __compat_resume_fn_ ## name, \ +} +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) /* * Use this if you want to use the same suspend and resume callbacks for suspend * to RAM and hibernation.