diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2009-01-14 00:40:38 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-01-18 10:35:46 -0800 |
commit | e1e04d6acc86af7ed9160e73bab9dc6bc9e0e5cf (patch) | |
tree | 1789ed38298cab24a74ed343f6c45e644b190cc6 | |
parent | 939c599209d596d205cc44a7fb41b727f20fc459 (diff) |
PCI PM: Split PCI Express port suspend-resume
commit a79d682f789730dfabaebbb507c87a90c0671a62 upstream
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 2f7bb3f50992..6abfafc50c63 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -41,7 +41,6 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) { int retval; - pci_restore_state(dev); retval = pci_enable_device(dev); if (retval) return retval; @@ -50,23 +49,32 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) } #ifdef CONFIG_PM -static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) +static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state) { - int ret = pcie_port_device_suspend(dev, state); + return pcie_port_device_suspend(dev, state); - if (!ret) - ret = pcie_portdrv_save_config(dev); - return ret; +} + +static int pcie_portdrv_suspend_late(struct pci_dev *dev, pm_message_t state) +{ + return pci_save_state(dev); } static int pcie_portdrv_resume_early(struct pci_dev *dev) { + return pci_restore_state(dev); +} + +static int pcie_portdrv_resume(struct pci_dev *dev) +{ pcie_portdrv_restore_config(dev); return pcie_port_device_resume(dev); } #else +#define pcie_portdrv_suspend NULL #define pcie_portdrv_suspend_late NULL #define pcie_portdrv_resume_early NULL +#define pcie_portdrv_resume NULL #endif /* @@ -221,6 +229,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) /* If fatal, restore cfg space for possible link reset at upstream */ if (dev->error_state == pci_channel_io_frozen) { + pci_restore_state(dev); pcie_portdrv_restore_config(dev); pci_enable_pcie_error_reporting(dev); } @@ -282,8 +291,10 @@ static struct pci_driver pcie_portdriver = { .probe = pcie_portdrv_probe, .remove = pcie_portdrv_remove, + .suspend = pcie_portdrv_suspend, .suspend_late = pcie_portdrv_suspend_late, .resume_early = pcie_portdrv_resume_early, + .resume = pcie_portdrv_resume, .err_handler = &pcie_portdrv_err_handler, }; |