--- zzzz-none-000/linux-5.15.111/drivers/usb/host/xhci-ring.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-atom-6670-761/linux-5.15.111/drivers/usb/host/xhci-ring.c 2024-02-07 10:23:22.000000000 +0000 @@ -62,6 +62,16 @@ u32 field1, u32 field2, u32 field3, u32 field4, bool command_must_succeed); +#if defined (CONFIG_AVM_KERNEL) +/* 20180719 AVM/VGJ USB3 ports switchable */ +extern int usb3port_config; + +#define HUB_DEBOUNCE_TIMEOUT 2000 +#define HUB_DEBOUNCE_STEP 25 +#define HUB_DEBOUNCE_STABLE 100 +#endif + + /* * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA * address of the TRB. @@ -1952,6 +1962,50 @@ trace_xhci_handle_port_status(hcd_portnum, portsc); +#if defined (CONFIG_AVM_KERNEL) + /* 20180719 AVM/VGJ Disable USB3 if necessary when a device is connected */ + if ((hcd->speed == HCD_USB3) && (portsc & PORT_CONNECT)) { + if (!(usb3port_config & hcd_portnum)) { + int total_time; + + /* Disable Port as in xhci_hub_control */ + xhci_warn(xhci, "Disable port %d\n", hcd_portnum); + portsc = xhci_port_state_to_neutral(portsc); + /* + * Clear all change bits, so that we get a new + * connection event. + */ + portsc |= PORT_CSC | PORT_PEC | PORT_WRC | + PORT_OCC | PORT_RC | PORT_PLC | + PORT_CEC; + writel(portsc | PORT_PE, port->addr); + portsc = readl(port->addr); + + /* Wait for the link to enter the disabled state as in hub_usb3_port_disable */ + for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) { + portsc = readl(port->addr); + xhci_warn(xhci, "waiting for port %d to disable, status = 0x%x\n", hcd_portnum, portsc); + + if ((portsc & USB_PORT_STAT_LINK_STATE) == + USB_SS_PORT_LS_SS_DISABLED) + break; + if (total_time >= HUB_DEBOUNCE_TIMEOUT) + break; + msleep(HUB_DEBOUNCE_STEP); + } + } + } + + /* 20180719 AVM/VGJ Enable USB3 if necessary when a device is disconnected */ + if ((hcd->speed != HCD_USB3) && (portsc & PORT_CSC) && !(portsc & PORT_CONNECT)) { + if (!(usb3port_config & hcd_portnum)) { + /* Enable port */ + xhci_warn(xhci, "Enable port %d\n", hcd_portnum); + xhci_set_link_state(xhci, port, USB_SS_PORT_LS_RX_DETECT); + } + } +#endif + if (hcd->state == HC_STATE_SUSPENDED) { xhci_dbg(xhci, "resume root hub\n"); usb_hcd_resume_root_hub(hcd);