PCI: Put PCIe ports into D3 during suspend
authorMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 2 Jun 2016 08:17:12 +0000 (11:17 +0300)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 13 Jun 2016 19:57:36 +0000 (14:57 -0500)
commit9d26d3a8f1b0c442339a235f9508bdad8af91043
treefda7bf01c07d954d9dceb2a0f1c7a9beba74a67e
parent43f7f88b9362e1f26603b45932069bbd6e15a1e1
PCI: Put PCIe ports into D3 during suspend

Currently the Linux PCI core does not touch power state of PCI bridges and
PCIe ports when system suspend is entered.  Leaving them in D0 consumes
power unnecessarily and may prevent the CPU from entering deeper C-states.

With recent PCIe hardware we can power down the ports to save power given
that we take into account few restrictions:

  - The PCIe port hardware is recent enough, starting from 2015.

  - Devices connected to PCIe ports are effectively in D3cold once the port
    is transitioned to D3 (the config space is not accessible anymore and
    the link may be powered down).

  - Devices behind the PCIe port need to be allowed to transition to D3cold
    and back.  There is a way both drivers and userspace can forbid this.

  - If the device behind the PCIe port is capable of waking the system it
    needs to be able to do so from D3cold.

This patch adds a new flag to struct pci_device called 'bridge_d3'.  This
flag is set and cleared by the PCI core whenever there is a change in power
management state of any of the devices behind the PCIe port.  When system
later on is suspended we only need to check this flag and if it is true
transition the port to D3 otherwise we leave it in D0.

Also provide override mechanism via command line parameter
"pcie_port_pm=[off|force]" that can be used to disable or enable the
feature regardless of the BIOS manufacturing date.

Tested-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Documentation/kernel-parameters.txt
drivers/pci/bus.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/remove.c
drivers/usb/host/xhci-pci.c
include/linux/pci.h