Re: [RFT 2/2] xhci: Disable D3cold for buggy TI redrivers.

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

 



Hi Sarah and Alan,
  I am curious whether the the PME- to PME+ happening on a suspended
TI host controller could be used as some hack to signal the mis-behaving
redriver. Could such transition be used as a trigger for linux kernel to
wakeup the TI host "manually"? I am referring to step 4. of my test
in http://marc.info/?l=linux-acpi&m=136735488916468&w=3 showing the
suspended TI controller (in step 3) is not completely "dead" and at least
some part of it gets power enabled (PME+) as a result of port status change
event (mouse connect):

<quote>
4. Interestingly, if I connect a mouse to the socket to show it is "dead" there is a tiny change in lspci:

--- lspci_vvv_initial__1c.4_and_0b:00_to_auto__mouse_attached_and_works__detached.txt   2013-04-20 01:10:06.000000000 +0200
+++ lspci_vvv_initial__1c.4_and_0b:00_to_auto__mouse_attached_and_works__detached__reattached_but_dead.txt      2013-04-20 01:10:28.000000000 +0200
@@ -491,7 +491,7 @@
        Region 2: Memory at f7d10000 (64-bit, non-prefetchable) [size=8K]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=100mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
-               Status: D3 NoSoftRst+ PME-Enable+ DSel=0 DScale=0 PME-
+               Status: D3 NoSoftRst+ PME-Enable+ DSel=0 DScale=0 PME+
        Capabilities: [48] MSI: Enable- Count=1/8 Maskable- 64bit+
                Address: 0000000000000000  Data: 0000
        Capabilities: [70] Express (v2) Endpoint, MSI 00

</quote>

The suspended TI host controller was in PME- state. A mouse connect to the
xHCI port resulted in "deadly suspend" (TI host now in PME+) or maybe I could
better say it was woken up only partially (mouse gets NO power whereas the PCI
device DOES get its power ("PME+")? I used to say a deadly suspend happened
but after I realized this PME- to PME+ change I thing the situation is not that
bad for us, users.

sure, the mouse still does not get power at step 4. (mouse red light is off)
but if this PME- to PME+ could be used a a sign for the broken redriver, I wish
linux could do

echo on > /sys/bus/pci/devices/0000\:0b\:00.0/power/control

for me automatically, right?



I remember the initial posting in May 2012:
http://markmail.org/message/n3qbgspt76yyxvky
Workaround required for Texas Instruments USB3 re-driver

while I have now realized that there was an on ongoing discussion later on:

http://marc.info/?l=linux-kernel&m=134402069909506&w=2
usb: host: xhci: Fix Compliance Mode on SN65LVPE502CP Hardware

I propose you add relevant URLs to the patch.

Martin
P.S.: Have Dell Vostro 3550 with likely the broken redriver but did not
physically crack the laptop, sorry.


Sarah Sharp wrote:
> Some xHCI hosts contain a "redriver" from TI that silently drops port
> status connect changes if the port slips into Compliance Mode.  If the
> port slips into compliance mode while the host is in D0, there will not
> be a port status change event.  If the port slips into compliance mode
> while the host is in D3, the host will not send a PME.  This includes
> when the system is suspended (S3) or hibernated (S4).
> 
> If this happens when the system is in S3/S4, there is nothing software
> can do.  Other port status change events that would normally cause the
> host to wake the system from S3/S4 may also be lost.  This includes
> remote wakeup, disconnects and connects on other ports, and overrcurrent
> events.  A decision was made to _NOT_ disable system suspend/hibernate
> on these systems, since users are unlikely to enable wakeup from S3/S4
> for the xHCI host.
> 
> Software can deal with this issue when the system is in S0.  A work
> around was put in to poll the port status registers for Compliance Mode.
> The xHCI driver will continue to poll the registers while the host is
> runtime suspended.  Unfortunately, that means we can't allow the PCI
> device to go into D3cold, because power will be removed from the host,
> and the config space will read as all Fs.
> 
> Disable D3cold in the xHCI PCI runtime suspend function.
> 
> This patch should be backported to kernels as old as 3.2, that
> contain the commit 71c731a296f1b08a3724bd1b514b64f1bda87a23 "usb: host:
> xhci: Fix Compliance Mode on SN65LVPE502CP Hardware"
> 
> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> Cc: Huang Ying <ying.huang@xxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> ---
>  drivers/usb/host/xhci-pci.c |    8 ++++++++
>  drivers/usb/host/xhci.c     |    4 ++--
>  drivers/usb/host/xhci.h     |    3 +++
>  3 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
> index 1a30c38..cc24e39 100644
> --- a/drivers/usb/host/xhci-pci.c
> +++ b/drivers/usb/host/xhci-pci.c
> @@ -221,6 +221,14 @@ static void xhci_pci_remove(struct pci_dev *dev)
>  static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
>  {
>  	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
> +	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
> +
> +	/*
> +	 * Systems with the TI redriver that loses port status change events
> +	 * need to have the registers polled during D3, so avoid D3cold.
> +	 */
> +	if (xhci_compliance_mode_recovery_timer_quirk_check())
> +		pdev->no_d3cold = true;
>  
>  	return xhci_suspend(xhci);
>  }
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index ae59119..d8f640b 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
>   * Systems:
>   * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
>   */
> -static bool compliance_mode_recovery_timer_quirk_check(void)
> +bool xhci_compliance_mode_recovery_timer_quirk_check(void)
>  {
>  	const char *dmi_product_name, *dmi_sys_vendor;
>  
> @@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
>  	xhci_dbg(xhci, "Finished xhci_init\n");
>  
>  	/* Initializing Compliance Mode Recovery Data If Needed */
> -	if (compliance_mode_recovery_timer_quirk_check()) {
> +	if (xhci_compliance_mode_recovery_timer_quirk_check()) {
>  		xhci->quirks |= XHCI_COMP_MODE_QUIRK;
>  		compliance_mode_recovery_timer_init(xhci);
>  	}
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index 29c978e..77600ce 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -1853,4 +1853,7 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
>  struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
>  struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
>  
> +/* xHCI quirks */
> +bool xhci_compliance_mode_recovery_timer_quirk_check(void);
> +
>  #endif /* __LINUX_XHCI_HCD_H */
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




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

  Powered by Linux