Skip to content

Commit

Permalink
PCI: Check for PME in targeted sleep state
Browse files Browse the repository at this point in the history
One some systems, the firmware does not allow certain PCI devices to be put
in deep D-states.  This can cause problems for wakeup signalling, if the
device does not support PME# in the deepest allowed suspend state.  For
example, Pierre reports that on his system, ACPI does not permit his xHCI
host controller to go into D3 during runtime suspend -- but D3 is the only
state in which the controller can generate PME# signals.  As a result, the
controller goes into runtime suspend but never wakes up, so it doesn't work
properly.  USB devices plugged into the controller are never detected.

If the device relies on PME# for wakeup signals but is not capable of
generating PME# in the target state, the PCI core should accurately report
that it cannot do wakeup from runtime suspend.  This patch modifies the
pci_dev_run_wake() routine to add this check.

Reported-by: Pierre de Villemereuil <[email protected]>
Tested-by: Pierre de Villemereuil <[email protected]>
Signed-off-by: Alan Stern <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
CC: [email protected]
CC: Lukas Wunner <[email protected]>
  • Loading branch information
AlanStern authored and bjorn-helgaas committed Nov 11, 2016
1 parent 1001354 commit 6496ebd
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions drivers/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2106,6 +2106,10 @@ bool pci_dev_run_wake(struct pci_dev *dev)
if (!dev->pme_support)
return false;

/* PME-capable in principle, but not from the intended sleep state */
if (!pci_pme_capable(dev, pci_target_state(dev)))
return false;

while (bus->parent) {
struct pci_dev *bridge = bus->self;

Expand Down

0 comments on commit 6496ebd

Please sign in to comment.