From: William Wu Date: Tue, 21 Feb 2017 08:41:55 +0000 (+0800) Subject: usb: host: xhci: set xhci autosuspend quirk based on platform data X-Git-Tag: firefly_0821_release~581 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4eab21e6bfb95170da69def04e7369701c301096;p=firefly-linux-kernel-4.4.55.git usb: host: xhci: set xhci autosuspend quirk based on platform data Some USB controllers (such as rk3328 SoC DWC3 controller with INNO USB 3.0 PHY) don't support autosuspend well, when receive remote wakeup signal from autosuspend, the Port Link State training failed, the correct PLC is Resume->Recovery->U0, but when the issue happens, the wrong PLC is Resume->Recovery->Inactive, cause resuming SS port fail. This issue always occurs when connect with external USB 3.0 HUB. This patch add a quirk to disable autosuspend function, and add new 'usb3_disable_autosuspend' member in xHCI platform data to support set the quirk based on platform data. Change-Id: Ice01d70178206e22658660361dd3a525046cbcf5 Signed-off-by: William Wu --- diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 8f54e5b97a04..fe7de8a58ef5 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -172,6 +172,9 @@ static int xhci_plat_probe(struct platform_device *pdev) (pdata && pdata->usb3_lpm_capable)) xhci->quirks |= XHCI_LPM_SUPPORT; + if (pdata && pdata->usb3_disable_autosuspend) + xhci->quirks |= XHCI_DIS_AUTOSUSPEND; + hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); if (IS_ERR(hcd->usb_phy)) { ret = PTR_ERR(hcd->usb_phy); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c4e2b1886f5d..a51d88ebf0b3 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "xhci.h" #include "xhci-trace.h" @@ -4903,6 +4904,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) /* xHCI private pointer was set in xhci_pci_probe for the second * registered roothub. */ + if (xhci->quirks & XHCI_DIS_AUTOSUSPEND) + xhci->shared_hcd->self.root_hub->quirks |= + USB_QUIRK_AUTO_SUSPEND; + return 0; } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 99ac2289dbf3..8de8cdabc955 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1631,6 +1631,7 @@ struct xhci_hcd { /* For controllers with a broken beyond repair streams implementation */ #define XHCI_BROKEN_STREAMS (1 << 19) #define XHCI_PME_STUCK_QUIRK (1 << 20) +#define XHCI_DIS_AUTOSUSPEND (1 << 21) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h index 6b3c1046b8e0..cd03e02f5c9a 100644 --- a/include/linux/usb/xhci_pdriver.h +++ b/include/linux/usb/xhci_pdriver.h @@ -21,11 +21,14 @@ * @xhci_slow_suspend: set if this xhci platform need an extraordinary * delay to wait for xHC enter the Halted state * after the Run/Stop (R/S) bit is cleared to '0'. + * @usb3_disable_autosuspend: determines if this xhci platform supports + * USB3 autosuspend capability * */ struct usb_xhci_pdata { unsigned usb3_lpm_capable:1; unsigned xhci_slow_suspend:1; + unsigned usb3_disable_autosuspend:1; }; #endif /* __USB_CORE_XHCI_PDRIVER_H */