Re: USB hotplug on HP 255 G6 laptop

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 16.10.2018 14:38, Jan Kara wrote:
On Wed 03-10-18 16:46:05, Jan Kara wrote:
On Wed 03-10-18 17:19:33, Mathias Nyman wrote:
On 02.10.2018 17:53, Jan Kara wrote:
On Tue 02-10-18 17:01:54, Mathias Nyman wrote:
On 02.10.2018 16:06, Jan Kara wrote:
Hello,

my wife has HP 255 G6 laptop. When it is attached to AC, everything works
as expected however when it is running on battery, USB hotplug stops
working - newly plugged devices do not appear to be visible to the kernel.
Only when the AC is plugged back in, the kernel suddently wakes up and
detects all newly attached devices. Maybe it is related to some power
management? Any idea how to debug this? Dmesg from the system is attached.
The kernels I've tested with (both behave the same way) are 4.18.11 kernel
and also openSUSE Leap 15 kernel which is 4.12-based. Thanks in advance for
any help.


Are you running laptop mode tools or similar that would enable runtime suspend
D3 state for xhci controller?

It is openSUSE Leap 15 installation with xfce4 desktop so I assume there is
some power-management going on. Not sure what I should look for but there's
xfce4-power-manager running, also upowerd is running.

what does lspci -vv say?

Attached.

check the content of the following files while running on battery:

cat /sys/bus/pci/devices/0000:00:10.0/firmware_node/power_state

D0

cat /sys/bus/pci/devices/0000:00:10.0/power/control

auto - when on battery, on - when on AC.

try: echo on > /sys/bus/pci/devices/0000:00:10.0/power/control
before pluggin in a usb device, does it help?

Yes, USB device gets recognized after this.


To me this looks like xhci is runtime suspended, but controller is still
in a PCI D0 state.

Normally the xHC should be put to PCI D3 in runtime suspend,  and woken
up by a PCI PME# when a device is plugged in, but PME# is not enabled in
D0 so in this case nothing wakes up the xHC.

The xhci runtime suspend code already stopped the controller, so probably
you're not getting an interrupt either.

PCI code looks at firmware ACPI tables to choose the suspend D state, if
something is off in the tables it's possible the wrong state is chosen.
worth checking.

Could you dump the DSDT ACPI table form /sys/firmware/acpi/tables/DSDT

Sure. Attached.

As a quick temporary workaround you could find and prevent the
powersaving program from enabling runtime suspend. (make sure it won't
write "auto" to /sys/bus/pci/devices/0000:00:10.0/power/control)

OK, thanks for the hint.

Any news here? Are really ACPI tables wrong on this laptop?


Can't say for sure

There might be differences how Windows and Linux parse ACPI tables.

If _PR0  or _PS0 is present for a device in ACPI tables then Linux will
assume the device is ACPI power manageable, and select PCI D states from ACPI tables.

_S3W should return the highest D-value (deepest sleep state) device can wake up from S3 (system suspend)
_S0W should return the highest D-value (deepest sleep state) device can wake up from S0 (Runtime suspend)

Your ACPI DSDT table shows:

    Scope (_SB.PCI0.XHC0)
    {
        Name (_PR0, Package (0x01)  // _PR0: Power Resources for D0
        {
            P0U3
        })
        Name (_PR3, Package (0x01)  // _PR3: Power Resources for D3hot
        {
            P3U3
        })
        Method (_S0W, 0, NotSerialized)  // _S0W: S0 Device Wake State
        {
            If ((XHCD == One))
            {
                Return (0x04)
            }
            Else
            {
                Return (Zero)
            }
        }

        Method (_S3W, 0, NotSerialized)  // _S3W: S3 Device Wake State
        {
            Return (0x04)
        }


Those with better APCI and PCI knowledge might know more details, or better debugging for this,
but it at least would be possible to check which D state is chosen by adding the below code,
and recompiling the kernel:


diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index c2ab577..c9cb93a 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -501,6 +501,12 @@ 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) {
+               dev_err(&pdev->dev, "HACK: device 0x%x: ACPI selected D%d state, Force D3\n",
+                       pdev->device, acpi_state);
+               acpi_state = ACPI_STATE_D3_HOT;
+       }
        if (acpi_state < 0)
                return PCI_POWER_ERROR;

You need to change the "0x31a8" to whatever PCI ID your xhci controller has.
lspci -nn is your friend.

-Mathias



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux