PCI runtime PM issue on NEC xHCI host

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

 



Linus, Keith, and Paul,

Can you try the attached patch and see if it helps your issues with
enabling runtime PM for the NEC USB 3.0 host controller?  You may have
to increase the timeout for your system.


Hi Rafael,

I mentioned I've been seeing failures when PCI runtime PM was enabled on
the xHCI host controller in my Lenovo x220.  It turns out that several
people have the same NEC chipset in other Lenovo models, and are also
experiencing similar issues.  When runtime PM is enabled for the host,
and you plug in a device, we get a steady stream of:

Oct 31 16:11:31 puck kernel: [ 5196.504007] xhci_hcd 0000:0e:00.0: PME# enabled
Oct 31 16:11:40 puck kernel: [ 5205.503185] xhci_hcd 0000:0e:00.0: PME# disabled
Oct 31 16:11:40 puck kernel: [ 5205.503202] xhci_hcd 0000:0e:00.0: setting latency timer to 64

Those three lines are repeated, but the new USB device never enumerates.

I've discovered that if I add a small delay in the xhci_resume function
(which is invoked by the dev_pm_ops resume method), then the host
controller has time to issue an interrupt about the port status change
before the runtime PM core puts it back into PCI suspend.

I'm running Linus' latest tree as of yesterday (commit 839d8810), which
includes your commit 379021d "PCI / PM: Extend PME polling to all PCI
devices".

Without any delays:

Oct 31 16:11:31 puck kernel: [ 5196.484738] xhci_suspend started
Oct 31 16:11:31 puck kernel: [ 5196.503891] xhci_hcd 0000:0e:00.0: hcd_pci_runtime_suspend: 0
Oct 31 16:11:31 puck kernel: [ 5196.504007] xhci_hcd 0000:0e:00.0: PME# enabled
Oct 31 16:11:40 puck kernel: [ 5205.503185] xhci_hcd 0000:0e:00.0: PME# disabled
Oct 31 16:11:40 puck kernel: [ 5205.503202] xhci_hcd 0000:0e:00.0: setting latency timer to 64
Oct 31 16:11:40 puck kernel: [ 5205.503207] xhci_resume started
Oct 31 16:11:40 puck kernel: [ 5205.503247] xhci_resume done
Oct 31 16:11:40 puck kernel: [ 5205.503248] xhci_hcd 0000:0e:00.0: hcd_pci_runtime_resume: 0
Oct 31 16:11:40 puck kernel: [ 5205.503255] xhci_suspend started
Oct 31 16:11:40 puck kernel: [ 5205.509289] xhci_hcd 0000:0e:00.0: hcd_pci_runtime_suspend: 0
Oct 31 16:11:40 puck kernel: [ 5205.509359] xhci_hcd 0000:0e:00.0: PME# enabled

Note the very small amount of time between xhci_resume being done and
xhci_suspend being started.

If I put a delay at the end of xhci_resume (as small as 30us) before
returning success, the interrupt for the port status change has time to
come in:

Nov  1 06:45:19 puck kernel: [57557.041234] xhci_suspend started
Nov  1 06:45:19 puck kernel: [57557.059419] xhci_hcd 0000:0e:00.0: hcd_pci_runtime_suspend: 0
Nov  1 06:45:19 puck kernel: [57557.059513] xhci_hcd 0000:0e:00.0: PME# enabled
Nov  1 06:45:27 puck kernel: [57565.060976] xhci_hcd 0000:0e:00.0: PME# disabled
Nov  1 06:45:27 puck kernel: [57565.060994] xhci_hcd 0000:0e:00.0: setting latency timer to 64
Nov  1 06:45:27 puck kernel: [57565.060999] xhci_resume started
Nov  1 06:45:27 puck kernel: [57565.061039] xhci_resume done
Nov  1 06:45:27 puck kernel: [57565.061071] xhci_hcd 0000:0e:00.0: hcd_pci_runtime_resume: 0
Nov  1 06:45:27 puck kernel: [57565.061079] xhci_suspend started
Nov  1 06:45:27 puck kernel: [57565.061082] xhci_irq
Nov  1 06:45:27 puck kernel: [57565.061085] Port Status Change Event for port 3
Nov  1 06:45:27 puck kernel: [57565.067076] xhci_resume started
Nov  1 06:45:27 puck kernel: [57565.067119] xhci_resume done
Nov  1 06:45:27 puck kernel: [57565.067150] xhci_hcd 0000:0e:00.0: hcd_pci_runtime_suspend: -16
Nov  1 06:45:27 puck kernel: [57565.067158] pci_pm_runtime_suspend(): hcd_pci_runtime_suspend+0x0/0x50 returns -16

Maybe resume takes too long, and the runtime PM system needs to mark the device
as busy when the runtime_resume function returns?  Catting the
power/autosuspend_delay_ms file returns an I/O error:

root@puck:/sys/bus/pci/devices/0000:0e:00.0# cat power/autosuspend_delay_ms
cat: power/autosuspend_delay_ms: Input/output error

Any thoughts on this?  I can certainly add the attached patch to the
xHCI driver, but it seems like there is something fundamentally broken
in the runtime PM core if it's suspending devices without giving them a
chance to interrupt.

Sarah Sharp
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 1ff95a0..e238360 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -914,6 +914,9 @@ failed_restart:
 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
 
 	spin_unlock_irq(&xhci->lock);
+
+	if (xhci->quirks & XHCI_NEC_HOST)
+		udelay(30);
 	return 0;
 }
 #endif	/* CONFIG_PM */

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux