Commit a79d682f authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Jesse Barnes

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: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent f06fc0b6
...@@ -41,7 +41,6 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) ...@@ -41,7 +41,6 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
{ {
int retval; int retval;
pci_restore_state(dev);
retval = pci_enable_device(dev); retval = pci_enable_device(dev);
if (retval) if (retval)
return retval; return retval;
...@@ -50,23 +49,32 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) ...@@ -50,23 +49,32 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
} }
#ifdef CONFIG_PM #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) 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); pcie_portdrv_restore_config(dev);
return pcie_port_device_resume(dev); return pcie_port_device_resume(dev);
} }
#else #else
#define pcie_portdrv_suspend NULL
#define pcie_portdrv_suspend_late NULL #define pcie_portdrv_suspend_late NULL
#define pcie_portdrv_resume_early NULL #define pcie_portdrv_resume_early NULL
#define pcie_portdrv_resume NULL
#endif #endif
/* /*
...@@ -221,6 +229,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) ...@@ -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 fatal, restore cfg space for possible link reset at upstream */
if (dev->error_state == pci_channel_io_frozen) { if (dev->error_state == pci_channel_io_frozen) {
pci_restore_state(dev);
pcie_portdrv_restore_config(dev); pcie_portdrv_restore_config(dev);
pci_enable_pcie_error_reporting(dev); pci_enable_pcie_error_reporting(dev);
} }
...@@ -282,8 +291,10 @@ static struct pci_driver pcie_portdriver = { ...@@ -282,8 +291,10 @@ static struct pci_driver pcie_portdriver = {
.probe = pcie_portdrv_probe, .probe = pcie_portdrv_probe,
.remove = pcie_portdrv_remove, .remove = pcie_portdrv_remove,
.suspend = pcie_portdrv_suspend,
.suspend_late = pcie_portdrv_suspend_late, .suspend_late = pcie_portdrv_suspend_late,
.resume_early = pcie_portdrv_resume_early, .resume_early = pcie_portdrv_resume_early,
.resume = pcie_portdrv_resume,
.err_handler = &pcie_portdrv_err_handler, .err_handler = &pcie_portdrv_err_handler,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment