aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2009-09-09 17:49:59 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-14 16:41:46 -0400
commit4b77b0a2ba27d64f58f16d8d4d48d8319dda36ff (patch)
tree957f38dc1065e2880197e7ca5ffe1592515010b3 /drivers/pci
parent999cce4a52d5abdda5d2cec6bac241899bc19e4c (diff)
PCI: Clear saved_state after the state has been restored
Some PCI devices fail if their standard configuration registers are restored twice in a row. Prevent this from happening by making pci_restore_state() clear the saved_state flag of the device right after the device's standard configuration registers have been populated with the previously saved values. Simplify PCI PM callbacks by removing the direct clearing of state_saved from them, as it shouldn't be necessary any more (except in pci_pm_thaw(), where it has to be cleared, so that the values saved during the "freeze" phase of hibernation are not used later by mistake). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-driver.c11
-rw-r--r--drivers/pci/pci.c3
-rw-r--r--drivers/pci/probe.c3
3 files changed, 8 insertions, 9 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index dbfc93cb5d01..ffc15e97d11c 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -445,8 +445,6 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
445 struct pci_dev * pci_dev = to_pci_dev(dev); 445 struct pci_dev * pci_dev = to_pci_dev(dev);
446 struct pci_driver * drv = pci_dev->driver; 446 struct pci_driver * drv = pci_dev->driver;
447 447
448 pci_dev->state_saved = false;
449
450 if (drv && drv->suspend) { 448 if (drv && drv->suspend) {
451 pci_power_t prev = pci_dev->current_state; 449 pci_power_t prev = pci_dev->current_state;
452 int error; 450 int error;
@@ -542,7 +540,6 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
542static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev) 540static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
543{ 541{
544 pci_restore_standard_config(pci_dev); 542 pci_restore_standard_config(pci_dev);
545 pci_dev->state_saved = false;
546 pci_fixup_device(pci_fixup_resume_early, pci_dev); 543 pci_fixup_device(pci_fixup_resume_early, pci_dev);
547} 544}
548 545
@@ -608,8 +605,6 @@ static int pci_pm_suspend(struct device *dev)
608 if (pci_has_legacy_pm_support(pci_dev)) 605 if (pci_has_legacy_pm_support(pci_dev))
609 return pci_legacy_suspend(dev, PMSG_SUSPEND); 606 return pci_legacy_suspend(dev, PMSG_SUSPEND);
610 607
611 pci_dev->state_saved = false;
612
613 if (!pm) { 608 if (!pm) {
614 pci_pm_default_suspend(pci_dev); 609 pci_pm_default_suspend(pci_dev);
615 goto Fixup; 610 goto Fixup;
@@ -744,8 +739,6 @@ static int pci_pm_freeze(struct device *dev)
744 if (pci_has_legacy_pm_support(pci_dev)) 739 if (pci_has_legacy_pm_support(pci_dev))
745 return pci_legacy_suspend(dev, PMSG_FREEZE); 740 return pci_legacy_suspend(dev, PMSG_FREEZE);
746 741
747 pci_dev->state_saved = false;
748
749 if (!pm) { 742 if (!pm) {
750 pci_pm_default_suspend(pci_dev); 743 pci_pm_default_suspend(pci_dev);
751 return 0; 744 return 0;
@@ -821,6 +814,8 @@ static int pci_pm_thaw(struct device *dev)
821 pci_pm_reenable_device(pci_dev); 814 pci_pm_reenable_device(pci_dev);
822 } 815 }
823 816
817 pci_dev->state_saved = false;
818
824 return error; 819 return error;
825} 820}
826 821
@@ -832,8 +827,6 @@ static int pci_pm_poweroff(struct device *dev)
832 if (pci_has_legacy_pm_support(pci_dev)) 827 if (pci_has_legacy_pm_support(pci_dev))
833 return pci_legacy_suspend(dev, PMSG_HIBERNATE); 828 return pci_legacy_suspend(dev, PMSG_HIBERNATE);
834 829
835 pci_dev->state_saved = false;
836
837 if (!pm) { 830 if (!pm) {
838 pci_pm_default_suspend(pci_dev); 831 pci_pm_default_suspend(pci_dev);
839 goto Fixup; 832 goto Fixup;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index dcdfb2212ca3..6edecff0b419 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -854,6 +854,7 @@ pci_restore_state(struct pci_dev *dev)
854 854
855 if (!dev->state_saved) 855 if (!dev->state_saved)
856 return 0; 856 return 0;
857
857 /* PCI Express register must be restored first */ 858 /* PCI Express register must be restored first */
858 pci_restore_pcie_state(dev); 859 pci_restore_pcie_state(dev);
859 860
@@ -875,6 +876,8 @@ pci_restore_state(struct pci_dev *dev)
875 pci_restore_msi_state(dev); 876 pci_restore_msi_state(dev);
876 pci_restore_iov_state(dev); 877 pci_restore_iov_state(dev);
877 878
879 dev->state_saved = false;
880
878 return 0; 881 return 0;
879} 882}
880 883
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 882383b61d30..8105e32117f6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1032,6 +1032,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
1032 /* Fix up broken headers */ 1032 /* Fix up broken headers */
1033 pci_fixup_device(pci_fixup_header, dev); 1033 pci_fixup_device(pci_fixup_header, dev);
1034 1034
1035 /* Clear the state_saved flag. */
1036 dev->state_saved = false;
1037
1035 /* Initialize various capabilities */ 1038 /* Initialize various capabilities */
1036 pci_init_capabilities(dev); 1039 pci_init_capabilities(dev);
1037 1040