diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-06-24 01:56:13 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-06-28 01:52:38 +0200 |
commit | 8370c2dc4c7b91be7e1231130f0ae08b5aebecf4 (patch) | |
tree | ee4c1a4d35ef7ed39107e61a8846f1db2405425f /drivers/pci/pci-acpi.c | |
parent | 4d183d04195318c8ee8bce048f3f9a89c0e2056d (diff) | |
download | linux-8370c2dc4c7b91be7e1231130f0ae08b5aebecf4.tar.gz linux-8370c2dc4c7b91be7e1231130f0ae08b5aebecf4.tar.bz2 linux-8370c2dc4c7b91be7e1231130f0ae08b5aebecf4.zip |
PCI / PM: Drop pme_interrupt flag from struct pci_dev
The pme_interrupt flag in struct pci_dev is set when PMEs generated
by the device are going to be signaled via root port PME interrupts.
Ironically enough, that information is only used by the code setting
up device wakeup through ACPI which returns as soon as it sees the
pme_interrupt flag set while setting up "remote runtime wakeup".
That is questionable, however, because in theory there may be PCIe
devices using out-of-band PME signaling under root ports handled
by the native PME code or devices requiring wakeup power setup to be
carried out by AML. For such devices, ACPI wakeup should be invoked
regardless of whether or not native PME signaling is used in general.
For this reason, drop the pme_interrupt flag and rework the code
using it which then allows the ACPI-based device wakeup handling
in PCI to be consolidated to use one code path for both "runtime
remote wakeup" and system wakeup (from sleep states).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r-- | drivers/pci/pci-acpi.c | 68 |
1 files changed, 15 insertions, 53 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index eb014b8ab01a..de255bc9736b 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -569,67 +569,29 @@ static pci_power_t acpi_pci_get_power_state(struct pci_dev *dev) return state_conv[state]; } -static bool acpi_pci_can_wakeup(struct pci_dev *dev) -{ - struct acpi_device *adev = ACPI_COMPANION(&dev->dev); - return adev ? acpi_device_can_wakeup(adev) : false; -} - -static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) +static int acpi_pci_propagate_wakeup(struct pci_bus *bus, bool enable) { while (bus->parent) { - if (!acpi_pm_set_device_wakeup(&bus->self->dev, enable)) - return; - bus = bus->parent; - } - - /* We have reached the root bus. */ - if (bus->bridge) - acpi_pm_set_device_wakeup(bus->bridge, enable); -} + if (acpi_pm_device_can_wakeup(&bus->self->dev)) + return acpi_pm_set_device_wakeup(&bus->self->dev, enable); -static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) -{ - if (acpi_pci_can_wakeup(dev)) - return acpi_pm_set_device_wakeup(&dev->dev, enable); - - acpi_pci_propagate_wakeup_enable(dev->bus, enable); - return 0; -} - -static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) -{ - while (bus->parent) { - struct pci_dev *bridge = bus->self; - - if (bridge->pme_interrupt) - return; - if (!acpi_pm_set_device_wakeup(&bridge->dev, enable)) - return; bus = bus->parent; } /* We have reached the root bus. */ - if (bus->bridge) - acpi_pm_set_device_wakeup(bus->bridge, enable); + if (bus->bridge) { + if (acpi_pm_device_can_wakeup(bus->bridge)) + return acpi_pm_set_device_wakeup(bus->bridge, enable); + } + return 0; } -static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) +static int acpi_pci_wakeup(struct pci_dev *dev, bool enable) { - /* - * Per PCI Express Base Specification Revision 2.0 section - * 5.3.3.2 Link Wakeup, platform support is needed for D3cold - * waking up to power on the main link even if there is PME - * support for D3cold - */ - if (dev->pme_interrupt && !dev->runtime_d3cold) - return 0; - - if (!acpi_pm_set_device_wakeup(&dev->dev, enable)) - return 0; + if (acpi_pm_device_can_wakeup(&dev->dev)) + return acpi_pm_set_device_wakeup(&dev->dev, enable); - acpi_pci_propagate_run_wake(dev->bus, enable); - return 0; + return acpi_pci_propagate_wakeup(dev->bus, enable); } static bool acpi_pci_need_resume(struct pci_dev *dev) @@ -653,8 +615,8 @@ static const struct pci_platform_pm_ops acpi_pci_platform_pm = { .set_state = acpi_pci_set_power_state, .get_state = acpi_pci_get_power_state, .choose_state = acpi_pci_choose_state, - .sleep_wake = acpi_pci_sleep_wake, - .run_wake = acpi_pci_run_wake, + .sleep_wake = acpi_pci_wakeup, + .run_wake = acpi_pci_wakeup, .need_resume = acpi_pci_need_resume, }; @@ -778,7 +740,7 @@ static void pci_acpi_setup(struct device *dev) device_set_wakeup_capable(dev, true); device_set_run_wake(dev, true); - acpi_pci_sleep_wake(pci_dev, false); + acpi_pci_wakeup(pci_dev, false); } static void pci_acpi_cleanup(struct device *dev) |