commit 4fdc1790e6a9ef22399c6bc6e63b80f4609f3b7e upstream.
On plug-in of my USB-C device, its USB_SS_PORT_LS_SS_INACTIVE
link state bit is set. Greping all the kernel for this bit shows
that the port status requests a warm-reset this way.
This just happens, if its the only device on the root hub, the hub
therefore resumes and the HCDs status_urb isn't yet available.
If a warm-reset request is detected, this sets the hubs event_bits,
which will prevent any auto-suspend and allows the hubs workqueue
to warm-reset the port later in port_event.
v1->v2:
-Resubmit the patch according to the rule of Backport patch.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/usb/core/hub.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b33ec768404b..22e233afc6f6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1128,6 +1128,11 @@ static void hub_activate(struct usb_hub *hub,
enum hub_activation_type type)
USB_SS_PORT_LS_POLLING))
need_debounce_delay = true;
+ /* Make sure a warm-reset request is handled by port_event */
+ if (type == HUB_RESUME &&
+ hub_port_warm_reset_required(hub, port1, portstatus))
+ set_bit(port1, hub->event_bits);
+
/* Clear status-change flags; we'll debounce later */
if (portchange & USB_PORT_STAT_C_CONNECTION) {
need_debounce_delay = true;
--
2.20.1
During polling phase after some device plug in type-c port,
if polling timeout three times, link state will goto inactive.
However this event not handle by the driver, which will cause
device can't be recognized. To fix this issue, if port link state
detected in inactive, record this event that will trigger a warm reset
to bring device identified by driver.
The patch is scheduled to be submitted to the kernel mainline in 2021.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/usb/core/hub.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b33ec768404b..22e233afc6f6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1128,6 +1128,11 @@ static void hub_activate(struct usb_hub *hub,
enum hub_activation_type type)
USB_SS_PORT_LS_POLLING))
need_debounce_delay = true;
+ /* Make sure a warm-reset request is handled by port_event */
+ if (type == HUB_RESUME &&
+ hub_port_warm_reset_required(hub, port1, portstatus))
+ set_bit(port1, hub->event_bits);
+
/* Clear status-change flags; we'll debounce later */
if (portchange & USB_PORT_STAT_C_CONNECTION) {
need_debounce_delay = true;
--
2.20.1
Some Zhaoxin xHCI controllers follow usb3.1 spec,
but only support gen1 speed 5G. While in Linux kernel,
if xHCI suspport usb3.1,root hub speed will show on 10G.
To fix this issue, read usb speed ID supported by xHCI
to determine root hub speed.
The patch is scheduled to be submitted to the kernel mainline in 2021.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/usb/host/xhci.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 65cc362717fc..6b67b58ef304 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5035,6 +5035,8 @@ int xhci_gen_setup(struct usb_hcd *hcd,
xhci_get_quirks_t get_quirks)
*/
struct device *dev = hcd->self.sysdev;
unsigned int minor_rev;
+ struct pci_dev *pdev = to_pci_dev(dev);
+ u8 ssp_support = 1, i;
int retval;
/* Accept arbitrarily long scatter-gather lists */
@@ -5089,9 +5091,25 @@ int xhci_gen_setup(struct usb_hcd *hcd,
xhci_get_quirks_t get_quirks)
hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
break;
}
+
+ /* usb3.1 has gen1 and gen2, Some zx's xHCI controller that follow
usb3.1 spec
+ * but only support gen1
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) {
+ ssp_support = 0;
+ for (i = 0; i < xhci->usb3_rhub.psi_count; i++) {
+ if (XHCI_EXT_PORT_PSIV(xhci->usb3_rhub.psi[i]) >= 5)
+ ssp_support = 1;
+ }
+ if (ssp_support != 1) {
+ hcd->speed = HCD_USB3;
+ hcd->self.root_hub->speed = USB_SPEED_SUPER;
+ }
+ }
+
xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n",
minor_rev,
- minor_rev ? "Enhanced " : "");
+ ssp_support ? "Enhanced " : "");
xhci->usb3_rhub.hcd = hcd;
/* xHCI private pointer was set in xhci_pci_probe for the second
--
2.20.1
Over Current condition is not standardized in the UHCI spec.
Zhaoxin UHCI controllers report Over Current active off.
Intel controllers report it active on, so we'll adjust the bit value.
The patch is scheduled to be submitted to the kernel mainline in 2021.
Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com>
---
drivers/usb/host/uhci-pci.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c
index 0dd944277c99..3c0d4c43b640 100644
--- a/drivers/usb/host/uhci-pci.c
+++ b/drivers/usb/host/uhci-pci.c
@@ -134,6 +134,9 @@ static int uhci_pci_init(struct usb_hcd *hcd)
if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
device_set_wakeup_capable(uhci_dev(uhci), true);
+ if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_ZHAOXIN)
+ uhci->oc_low = 1;
+
/* Set up pointers to PCI-specific functions */
uhci->reset_hc = uhci_pci_reset_hc;
uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc;
--
2.20.1