Message ID | 2207145.ElGaqSPkdT@kreacher (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Bjorn Helgaas |
Headers | show |
Series | PCI: PM: Fix handling of device that can only signal PME from D3cold | expand |
On Thu, Jul 29, 2021 at 4:49 PM Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > It is inconsistent to return PCI_D0 from pci_target_state() instead > of the original target state if 'wakeup' is true and the device > cannot signal PME from D0. > > This only happens when the device cannot signal PME from the original > target state and any shallower power states (including D0) and that > case is effectively equivalent to the one in which PME signaling is > not supported at all. Since the original target state is returned in > the latter case, make the function do that in the former one too. > > Link: https://lore.kernel.org/linux-pm/3149540.aeNJFYEL58@kreacher/ > Fixes: 666ff6f83e1d ("PCI/PM: Avoid using device_may_wakeup() for runtime PM") > Reported-by: Mika Westerberg <mika.westerberg@linux.intel.com> > Reported-by: Utkarsh H Patel <utkarsh.h.patel@intel.com> > Reported-by: Koba Ko <koba.ko@canonical.com> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> The subject of this patch should be different, let me resend it.
Index: linux-pm/drivers/pci/pci.c =================================================================== --- linux-pm.orig/drivers/pci/pci.c +++ linux-pm/drivers/pci/pci.c @@ -2595,16 +2595,20 @@ static pci_power_t pci_target_state(stru if (dev->current_state == PCI_D3cold) target_state = PCI_D3cold; - if (wakeup) { + if (wakeup && dev->pme_support) { + pci_power_t state = target_state; + /* * Find the deepest state from which the device can generate * PME#. */ - if (dev->pme_support) { - while (target_state - && !(dev->pme_support & (1 << target_state))) - target_state--; - } + while (state && !(dev->pme_support & (1 << state))) + state--; + + if (state) + return state; + else if (dev->pme_support & 1) + return PCI_D0; } return target_state;