--- zzzz-none-000/linux-4.9.218/drivers/usb/host/xhci.c 2020-04-02 15:20:41.000000000 +0000 +++ seale-7590ax-750/linux-4.9.218/drivers/usb/host/xhci.c 2023-03-29 10:59:07.000000000 +0000 @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include "xhci.h" #include "xhci-trace.h" @@ -39,6 +42,17 @@ #define PORT_WAKE_BITS (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E) +#if defined (CONFIG_GRX5_AVM_FRITZ_BOX) +/* 20190827 AVM/WKR USB3 ports switchable */ +int usb3port_config = 0; //default USB2 only +module_param(usb3port_config, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(usb3port_config, "Bitmask of allowed USB3 ports"); +#endif + +static void xhci_vbus_work_func(struct work_struct *work); +static DECLARE_DELAYED_WORK(xhci_vbus_work, xhci_vbus_work_func); +static int usb_power_gpio = -1; + /* Some 0.95 hardware can't handle the chain bit on a Link TRB being cleared */ static int link_quirk; module_param(link_quirk, int, S_IRUGO | S_IWUSR); @@ -564,6 +578,14 @@ /*-------------------------------------------------------------------------*/ +static void xhci_vbus_work_func(struct work_struct *work) +{ + if (usb_power_gpio >= 0) { + avm_gpio_out_bit(usb_power_gpio, 1); + pr_info("xHCI: delayed VBUS POWER on\n"); + } +} + static int xhci_run_finished(struct xhci_hcd *xhci) { if (xhci_start(xhci)) { @@ -576,6 +598,10 @@ if (xhci->quirks & XHCI_NEC_HOST) xhci_ring_cmd_db(xhci); + cancel_delayed_work_sync(&xhci_vbus_work); + pr_info("xHCI: delay VBUS POWER on for 100 ms\n"); + schedule_delayed_work(&xhci_vbus_work, msecs_to_jiffies(100)); + xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_run for USB3 roothub"); return 0; @@ -728,6 +754,13 @@ "xhci_stop completed - status = %x", readl(&xhci->op_regs->status)); mutex_unlock(&xhci->mutex); + + cancel_delayed_work_sync(&xhci_vbus_work); + + if (usb_power_gpio >= 0) { + avm_gpio_out_bit(usb_power_gpio, 0); + pr_info("xHCI: delayed VBUS POWER off\n"); + } } /* @@ -5101,6 +5134,8 @@ static int __init xhci_hcd_init(void) { + int ret; + /* * Check the compiler generated sizes of structures that must be laid * out in specific ways for hardware access. @@ -5122,6 +5157,13 @@ if (usb_disabled()) return -ENODEV; + ret = avm_get_hw_config(AVM_HW_CONFIG_VERSION, "gpio_avm_usb_power_enable", &usb_power_gpio, NULL); + if (ret < 0) + return ret; + + avm_gpio_ctrl(usb_power_gpio, GPIO_PIN, GPIO_OUTPUT_PIN); + avm_gpio_out_bit(usb_power_gpio, 0); + return 0; }