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

PCI PM: Introduce device flag wakeup_prepared

Introduce a new PCI device flag, wakeup_prepared, to prevent PCI
wake-up preparation code from being executed twice in a row for the
same device and for the same purpose.
Reviewed-by: default avatarMatthew Garrett <mjg59@srcf.ucam.org>
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent df8db91f
...@@ -1225,6 +1225,10 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) ...@@ -1225,6 +1225,10 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
if (enable && !device_may_wakeup(&dev->dev)) if (enable && !device_may_wakeup(&dev->dev))
return -EINVAL; return -EINVAL;
/* Don't do the same thing twice in a row for one device. */
if (!!enable == !!dev->wakeup_prepared)
return 0;
/* /*
* According to "PCI System Architecture" 4th ed. by Tom Shanley & Don * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don
* Anderson we should be doing PME# wake enable followed by ACPI wake * Anderson we should be doing PME# wake enable followed by ACPI wake
...@@ -1241,9 +1245,12 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) ...@@ -1241,9 +1245,12 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
error = platform_pci_sleep_wake(dev, true); error = platform_pci_sleep_wake(dev, true);
if (ret) if (ret)
ret = error; ret = error;
if (!ret)
dev->wakeup_prepared = true;
} else { } else {
platform_pci_sleep_wake(dev, false); platform_pci_sleep_wake(dev, false);
pci_pme_active(dev, false); pci_pme_active(dev, false);
dev->wakeup_prepared = false;
} }
return ret; return ret;
...@@ -1365,6 +1372,7 @@ void pci_pm_init(struct pci_dev *dev) ...@@ -1365,6 +1372,7 @@ void pci_pm_init(struct pci_dev *dev)
int pm; int pm;
u16 pmc; u16 pmc;
dev->wakeup_prepared = false;
dev->pm_cap = 0; dev->pm_cap = 0;
/* find PCI PM capability in list */ /* find PCI PM capability in list */
......
...@@ -241,6 +241,7 @@ struct pci_dev { ...@@ -241,6 +241,7 @@ struct pci_dev {
unsigned int d1_support:1; /* Low power state D1 is supported */ unsigned int d1_support:1; /* Low power state D1 is supported */
unsigned int d2_support:1; /* Low power state D2 is supported */ unsigned int d2_support:1; /* Low power state D2 is supported */
unsigned int no_d1d2:1; /* Only allow D0 and D3 */ unsigned int no_d1d2:1; /* Only allow D0 and D3 */
unsigned int wakeup_prepared:1;
#ifdef CONFIG_PCIEASPM #ifdef CONFIG_PCIEASPM
struct pcie_link_state *link_state; /* ASPM link state. */ struct pcie_link_state *link_state; /* ASPM link state. */
......
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