Re: Intel GemniLake xHCI connected devices can never wake up the system from suspend

From: Mathias Nyman
Date: Thu Mar 15 2018 - 12:08:44 EST


On 15.03.2018 15:28, Chris Chiu wrote:
On Thu, Mar 15, 2018 at 7:46 PM, Mathias Nyman
<mathias.nyman@xxxxxxxxxxxxxxx> wrote:
On 15.03.2018 06:40, Chris Chiu wrote:

Hi,
I have a ASUS AIO V222GA and another Acer Desktop XC-830 both
have Intel CPU J5005 and they both hit the same problem. The XHCI
connected USB keyboard/mouse can never wakeup the system from suspend.
It reminds me that similiar thing happens on ApolloLake too which
needs the XHCI_PME_STUCK_QUIRK to get it work. It's also mentioned in

https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/pentium-celeron-n-series-spec-update.pdf
page #14 for N-seris intel CPU. And I also find the same problem
description in
https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/silver-celeron-spec-update.pdf
page #16 for J-series Intel CPU. Seems that they have different
workaround so I can not simply apply XHCI_PME_STUCK_QUIRK to make it
work.

Anyone can help here?


N-Series
CHP8: USB xHCI Controller May Not Re-Enter D3 State After a USB Wake Event
- needs XHCI_PME_STUCK_QUIRK in driver (sets bit 28 at offset 80a4)

Intel Pentium Silver N5000
Intel Pentium Silver J5005
Intel Celeron N4000 and N4100
Intel Celeron J4105 and J4005

USB xHCI Controller May Not Re-enter a D3 State After a USB Wake Even
Need to clear PME_EN bit of of the standard PCI PM_CSR register.
I think Linux does this anyway (clears enabling PME when reaching D0)
So if I remember correct there was no specific workaround needed for this.

what is the PCI ID of your xhci controller? (lspci -nn)

They're both 8086:31a8. So you mean from the workaround description, it should
work w/o any extra code? "Software should clear bit 8 (PME_EN) of PM_CSR" has
been handled somewhere else?


One other possible cause is that xHCI never reaches PCI device D3 suspend
state during system suspend.
xHC can't generate PME# wake event from normal running PCI device D0 state.

PCI code in Linux will check with ACPI about the lowest possible D state
when suspending,
If there is something missing from the xHCI entry in ACPI DSDT table it
might select D0.
as the suspend state, causing wake failure.


Here's the DSDT ASL of the ASUS machine.
https://gist.github.com/mschiu77/8e9c8a0e5a98b70a6dfff45620340bf1

Scope (_SB.PCI0.XHC) has _PS0 method, so Linux will look for a _S3W to get the
lowest possible D state in S3, but_S3W is missing, so Linux pci-acpi code will
probably default to D0



ASUS said the BIOS has no problem on USB wakeup under Windows so I don't think
there's any update. Anything else could be cause for this?

Linux and Windows probably check different DSDT values

You can try to force your xHC to D3 during suspend with a hack:

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 7815768..da46c52 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -488,6 +488,10 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
else
d_max = ACPI_STATE_D3_COLD;
acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL, d_max);
+
+ if (pdev->device == 0x31a8)
+ acpi_state = ACPI_STATE_D3_HOT;
+
if (acpi_state < 0)
return PCI_POWER_ERROR;
and see if usb wake starts to work

-Mathias