--- zzzz-none-000/linux-4.4.60/drivers/usb/host/xhci.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-7490-727/linux-4.4.60/drivers/usb/host/xhci.c 2021-02-04 17:41:59.000000000 +0000 @@ -29,6 +29,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" @@ -566,6 +580,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)) { @@ -578,6 +601,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; @@ -726,6 +756,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 } /* @@ -5041,6 +5082,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.