aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-01-22 17:38:31 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-01-27 12:47:02 -0500
commit48f67f54a53bb68619a63c3f38cf7f502ed74b1d (patch)
tree4a35f4b6319322104999b91a1b1b965ba2e94102
parent545ffd58adc86b8d33449dab44fe81b503a6f81b (diff)
PCI PM: Power up devices before restoring their state
Devices that have MSI-X enabled before suspend to RAM or hibernation and that are in a low power state during resume will not be handled correctly by pci_restore_standard_config(). Namely, it first calls pci_restore_state() which calls pci_restore_msi_state(), which in turn executes __pci_restore_msix_state() that accesses the device's memory space to restore the contents of the MSI-X table. However, if the device is in a low power state at this point, it's memory space is not accessible. The easiest way to fix this potential problem is to make pci_restore_standard_config() call pci_restore_state() after it has put the device into the full power state, D0. Fortunately, all of this is done with interrupts off, so the change of ordering should not cause any trouble. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r--drivers/pci/pci.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 17bd9325a245..f0aa3d533839 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1393,12 +1393,11 @@ int pci_restore_standard_config(struct pci_dev *dev)
1393 pci_power_t prev_state; 1393 pci_power_t prev_state;
1394 int error; 1394 int error;
1395 1395
1396 pci_restore_state(dev);
1397 pci_update_current_state(dev, PCI_D0); 1396 pci_update_current_state(dev, PCI_D0);
1398 1397
1399 prev_state = dev->current_state; 1398 prev_state = dev->current_state;
1400 if (prev_state == PCI_D0) 1399 if (prev_state == PCI_D0)
1401 return 0; 1400 goto Restore;
1402 1401
1403 error = pci_raw_set_power_state(dev, PCI_D0, false); 1402 error = pci_raw_set_power_state(dev, PCI_D0, false);
1404 if (error) 1403 if (error)
@@ -1421,7 +1420,8 @@ int pci_restore_standard_config(struct pci_dev *dev)
1421 1420
1422 dev->current_state = PCI_D0; 1421 dev->current_state = PCI_D0;
1423 1422
1424 return 0; 1423 Restore:
1424 return pci_restore_state(dev);
1425} 1425}
1426 1426
1427/** 1427/**