PCI / PM: Avoid resuming PCI devices during system suspend
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 21 Jan 2015 01:17:42 +0000 (02:17 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 23 Jan 2015 21:13:54 +0000 (22:13 +0100)
Commit f25c0ae2b4c4 (ACPI / PM: Avoid resuming devices in ACPI PM
domain during system suspend) modified the ACPI PM domain's system
suspend callbacks to allow devices attached to it to be left in the
runtime-suspended state during system suspend so as to optimize
the suspend process.

This was based on the general mechanism introduced by commit
aae4518b3124 (PM / sleep: Mechanism to avoid resuming runtime-suspended
devices unnecessarily).

Extend that approach to PCI devices by modifying the PCI bus type's
->prepare callback to return 1 for devices that are runtime-suspended
when it is being executed and that are in a suitable power state and
need not be resumed going forward.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.h

index 3542150..4890639 100644 (file)
@@ -501,12 +501,29 @@ static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
        return 0;
 }
 
+static bool acpi_pci_need_resume(struct pci_dev *dev)
+{
+       struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
+
+       if (!adev || !acpi_device_power_manageable(adev))
+               return false;
+
+       if (device_may_wakeup(&dev->dev) != !!adev->wakeup.prepare_count)
+               return true;
+
+       if (acpi_target_system_state() == ACPI_STATE_S0)
+               return false;
+
+       return !!adev->power.flags.dsw_present;
+}
+
 static struct pci_platform_pm_ops acpi_pci_platform_pm = {
        .is_manageable = acpi_pci_power_manageable,
        .set_state = acpi_pci_set_power_state,
        .choose_state = acpi_pci_choose_state,
        .sleep_wake = acpi_pci_sleep_wake,
        .run_wake = acpi_pci_run_wake,
+       .need_resume = acpi_pci_need_resume,
 };
 
 void acpi_pci_add_bus(struct pci_bus *bus)
Simple merge
Simple merge
Simple merge