--- zzzz-none-000/linux-4.4.271/drivers/usb/host/xhci.c 2021-06-03 06:22:09.000000000 +0000 +++ maple-fsgw-759/linux-4.4.271/drivers/usb/host/xhci.c 2023-12-20 10:37:30.000000000 +0000 @@ -30,6 +30,20 @@ #include #include +#if defined (CONFIG_AVM_KERNEL) +#include +#include +#include + +static int usb_power_gpio = -1; +static struct delayed_work xhci_vbus_work; + +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 + #include "xhci.h" #include "xhci-trace.h" @@ -564,6 +578,15 @@ /*-------------------------------------------------------------------------*/ +#if defined (CONFIG_AVM_KERNEL) +static void xhci_vbus_work_func(struct work_struct *work) { + if(usb_power_gpio > 0) { + avm_gpio_out_bit(usb_power_gpio , 1); /*--- VBUS ON ---*/ + printk(KERN_INFO "xHCI: delayed VBUS POWER on\n"); + } +} +#endif + static int xhci_run_finished(struct xhci_hcd *xhci) { if (xhci_start(xhci)) { @@ -576,6 +599,13 @@ if (xhci->quirks & XHCI_NEC_HOST) xhci_ring_cmd_db(xhci); +#if defined (CONFIG_AVM_KERNEL) + /* 20180814 AVM/WKR delay VBUS power after host initialization */ + cancel_delayed_work_sync(&xhci_vbus_work); + printk(KERN_INFO "xHCI: delay VBUS POWER on for 50 ms\n"); + schedule_delayed_work(&xhci_vbus_work, msecs_to_jiffies(50)); +#endif + xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_run for USB3 roothub"); return 0; @@ -724,6 +754,17 @@ "xhci_stop completed - status = %x", readl(&xhci->op_regs->status)); mutex_unlock(&xhci->mutex); + +#if defined (CONFIG_AVM_KERNEL) + cancel_delayed_work_sync(&xhci_vbus_work); + + /* 20171108 AVM/VGJ - Turn off port power */ + if(usb_power_gpio > 0) { + avm_gpio_out_bit(usb_power_gpio , 0); /*--- VBUS OFF ---*/ + } + + printk(KERN_INFO "xHCI: PORT POWER off"); +#endif } /* @@ -5122,6 +5163,17 @@ static int __init xhci_hcd_init(void) { +#if defined (CONFIG_AVM_KERNEL) + /* 20171108 AVM/VGJ - Get VBUS power pin and initialize it */ + int retval = avm_get_hw_config(AVM_HW_CONFIG_VERSION, "gpio_avm_usb_power_enable", &usb_power_gpio, NULL); + if (retval >= 0) { + avm_gpio_ctrl(usb_power_gpio, GPIO_PIN, GPIO_OUTPUT_PIN); + avm_gpio_out_bit(usb_power_gpio, 0); /* VBUS off */ + } + + INIT_DELAYED_WORK(&xhci_vbus_work, xhci_vbus_work_func); +#endif + /* * Check the compiler generated sizes of structures that must be laid * out in specific ways for hardware access.