Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI PM: Split PCI Express port suspend-resume

Suspend-resume of PCI Express ports has recently been moved into
_suspend_late() and _resume_early() callbacks, but some functions
executed from there should not be called with interrupts disabled,
eg. pci_enable_device(). For this reason, split the suspend-resume
of PCI Express ports into parts to be executed with interrupts
disabled and with interrupts enabled.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

authored by

Rafael J. Wysocki and committed by
Jesse Barnes
a79d682f f06fc0b6

+17 -6
+17 -6
drivers/pci/pcie/portdrv_pci.c
··· 41 41 { 42 42 int retval; 43 43 44 - pci_restore_state(dev); 45 44 retval = pci_enable_device(dev); 46 45 if (retval) 47 46 return retval; ··· 49 50 } 50 51 51 52 #ifdef CONFIG_PM 53 + static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) 54 + { 55 + return pcie_port_device_suspend(dev, state); 56 + 57 + } 58 + 52 59 static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) 53 60 { 54 - int ret = pcie_port_device_suspend(dev, state); 55 - 56 - if (!ret) 57 - ret = pcie_portdrv_save_config(dev); 58 - return ret; 61 + return pci_save_state(dev); 59 62 } 60 63 61 64 static int pcie_portdrv_resume_early(struct pci_dev *dev) 65 + { 66 + return pci_restore_state(dev); 67 + } 68 + 69 + static int pcie_portdrv_resume(struct pci_dev *dev) 62 70 { 63 71 pcie_portdrv_restore_config(dev); 64 72 return pcie_port_device_resume(dev); 65 73 } 66 74 #else 75 + #define pcie_portdrv_suspend NULL 67 76 #define pcie_portdrv_suspend_late NULL 68 77 #define pcie_portdrv_resume_early NULL 78 + #define pcie_portdrv_resume NULL 69 79 #endif 70 80 71 81 /* ··· 229 221 230 222 /* If fatal, restore cfg space for possible link reset at upstream */ 231 223 if (dev->error_state == pci_channel_io_frozen) { 224 + pci_restore_state(dev); 232 225 pcie_portdrv_restore_config(dev); 233 226 pci_enable_pcie_error_reporting(dev); 234 227 } ··· 291 282 .probe = pcie_portdrv_probe, 292 283 .remove = pcie_portdrv_remove, 293 284 285 + .suspend = pcie_portdrv_suspend, 294 286 .suspend_late = pcie_portdrv_suspend_late, 295 287 .resume_early = pcie_portdrv_resume_early, 288 + .resume = pcie_portdrv_resume, 296 289 297 290 .err_handler = &pcie_portdrv_err_handler, 298 291 };