--- zzzz-none-000/linux-3.10.107/drivers/usb/host/ehci-hcd.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/usb/host/ehci-hcd.c 2021-02-04 17:41:59.000000000 +0000 @@ -71,7 +71,6 @@ static const char hcd_name [] = "ehci_hcd"; -#undef VERBOSE_DEBUG #undef EHCI_URB_TRACE /* magic numbers that can affect system performance */ @@ -103,6 +102,12 @@ module_param (ignore_oc, bool, S_IRUGO); MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); +#if defined(CONFIG_SOC_QCA955X) || defined(CONFIG_SOC_QCA956X) +static unsigned int fatal_counter = 0; +module_param (fatal_counter, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC (fatal_counter, "number of fatal errors"); +#endif + #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) /*-------------------------------------------------------------------------*/ @@ -110,6 +115,9 @@ #include "ehci.h" #include "pci-quirks.h" +static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE], + struct ehci_tt *tt); + /* * The MosChip MCS9990 controller updates its microframe counter * a little before the frame counter, and occasionally we will read @@ -139,7 +147,7 @@ /*-------------------------------------------------------------------------*/ /* - * handshake - spin reading hc until handshake completes or fails + * ehci_handshake - spin reading hc until handshake completes or fails * @ptr: address of hc register to be read * @mask: bits to look at in result of read * @done: value of those bits when handshake succeeds @@ -155,8 +163,8 @@ * before driver shutdown. But it also seems to be caused by bugs in cardbus * bridge shutdown: shutting down the bridge before the devices using it. */ -static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, - u32 mask, u32 done, int usec) +int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, + u32 mask, u32 done, int usec) { u32 result; @@ -172,6 +180,7 @@ } while (usec > 0); return -ETIMEDOUT; } +EXPORT_SYMBOL_GPL(ehci_handshake); /* check TDI/ARC silicon is in host mode */ static int tdi_in_host_mode (struct ehci_hcd *ehci) @@ -212,7 +221,7 @@ spin_unlock_irq(&ehci->lock); synchronize_irq(ehci_to_hcd(ehci)->irq); - return handshake(ehci, &ehci->regs->status, + return ehci_handshake(ehci, &ehci->regs->status, STS_HALT, STS_HALT, 16 * 125); } @@ -236,7 +245,7 @@ * Reset a non-running (STS_HALT == 1) controller. * Must be called with interrupts enabled and the lock not held. */ -static int ehci_reset (struct ehci_hcd *ehci) +int ehci_reset(struct ehci_hcd *ehci) { int retval; u32 command = ehci_readl(ehci, &ehci->regs->command); @@ -249,9 +258,40 @@ command |= CMD_RESET; dbg_cmd (ehci, "reset", command); ehci_writel(ehci, command, &ehci->regs->command); + + if (ehci->qca_force_host_mode) { + u32 usbmode; + + udelay(1000); + + usbmode = ehci_readl(ehci, &ehci->regs->usbmode); + usbmode |= USBMODE_CM_HC | (1 << 4); + ehci_writel(ehci, usbmode, &ehci->regs->usbmode); + + ehci_dbg(ehci, "forced host mode, usbmode: %08x\n", + ehci_readl(ehci, &ehci->regs->usbmode)); + } + + if (ehci->qca_force_16bit_ptw) { + u32 port_status; + + udelay(1000); + + /* enable 16-bit UTMI interface */ + port_status = ehci_readl(ehci, &ehci->regs->port_status[0]); + port_status |= BIT(28); + ehci_writel(ehci, port_status, &ehci->regs->port_status[0]); + + ehci_dbg(ehci, "16-bit UTMI interface enabled, status: %08x\n", + ehci_readl(ehci, &ehci->regs->port_status[0])); + } + + if (ehci->reset_notifier) + ehci->reset_notifier(ehci_to_hcd(ehci)); + ehci->rh_state = EHCI_RH_HALTED; ehci->next_statechange = jiffies; - retval = handshake (ehci, &ehci->regs->command, + retval = ehci_handshake(ehci, &ehci->regs->command, CMD_RESET, 0, 250 * 1000); if (ehci->has_hostpc) { @@ -272,6 +312,7 @@ ehci->resuming_ports = 0; return retval; } +EXPORT_SYMBOL_GPL(ehci_reset); /* * Idle the controller (turn off the schedules). @@ -286,7 +327,8 @@ /* wait for any schedule enables/disables to take effect */ temp = (ehci->command << 10) & (STS_ASS | STS_PSS); - handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, temp, 16 * 125); + ehci_handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, temp, + 16 * 125); /* then disable anything that's still active */ spin_lock_irq(&ehci->lock); @@ -295,7 +337,8 @@ spin_unlock_irq(&ehci->lock); /* hardware can take 16 microframes to turn off ... */ - handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, 0, 16 * 125); + ehci_handshake(ehci, &ehci->regs->status, STS_ASS | STS_PSS, 0, + 16 * 125); } /*-------------------------------------------------------------------------*/ @@ -306,6 +349,7 @@ static void ehci_work(struct ehci_hcd *ehci); static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); +static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable); #include "ehci-timer.c" #include "ehci-hub.c" @@ -324,9 +368,13 @@ { int port = HCS_N_PORTS(ehci->hcs_params); - while (port--) + while (port--) { + spin_unlock_irq(&ehci->lock); + ehci_port_power(ehci, port, false); + spin_lock_irq(&ehci->lock); ehci_writel(ehci, PORT_RWC_BITS, &ehci->regs->port_status[port]); + } } /* @@ -437,14 +485,6 @@ if (ehci->amd_pll_fix == 1) usb_amd_dev_put(); -#ifdef EHCI_STATS - ehci_dbg(ehci, "irq normal %ld err %ld iaa %ld (lost %ld)\n", - ehci->stats.normal, ehci->stats.error, ehci->stats.iaa, - ehci->stats.lost_iaa); - ehci_dbg (ehci, "complete %ld unlink %ld\n", - ehci->stats.complete, ehci->stats.unlink); -#endif - dbg_status (ehci, "ehci_stop completed", ehci_readl(ehci, &ehci->regs->status)); } @@ -484,10 +524,12 @@ ehci->periodic_size = DEFAULT_I_TDPS; INIT_LIST_HEAD(&ehci->async_unlink); INIT_LIST_HEAD(&ehci->async_idle); + INIT_LIST_HEAD(&ehci->intr_unlink_wait); INIT_LIST_HEAD(&ehci->intr_unlink); INIT_LIST_HEAD(&ehci->intr_qh_list); INIT_LIST_HEAD(&ehci->cached_itd_list); INIT_LIST_HEAD(&ehci->cached_sitd_list); + INIT_LIST_HEAD(&ehci->tt_list); if (HCC_PGM_FRAMELISTLEN(hcc_params)) { /* periodic schedule size can be smaller than default */ @@ -584,7 +626,7 @@ * streaming mappings for I/O buffers, like pci_map_single(), * can return segments above 4GB, if the device allows. * - * NOTE: the dma mask is visible through dma_supported(), so + * NOTE: the dma mask is visible through dev->dma_mask, so * drivers can pass this info along ... like NETIF_F_HIGHDMA, * Scsi_Host.highmem_io, and so forth. It's readonly to all * host side drivers though. @@ -634,7 +676,7 @@ "USB %x.%x started, EHCI %x.%02x%s\n", ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), temp >> 8, temp & 0xff, - ignore_oc ? ", overcurrent ignored" : ""); + (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : ""); ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ @@ -721,12 +763,20 @@ cmd = ehci_readl(ehci, &ehci->regs->command); bh = 0; -#ifdef VERBOSE_DEBUG - /* unrequested/ignored: Frame List Rollover */ - dbg_status (ehci, "irq", status); -#endif +#if defined(CONFIG_SOC_QCA955X) || defined(CONFIG_SOC_QCA956X) +#define STS_RX_OVERFLOW STS_FATAL + /* AVM/BC 25.03.2014: Atheros BSP */ + if (unlikely ((status & STS_RX_OVERFLOW) != 0)) { + fatal_counter++; + //ehci_dbg(ehci, "Rx Overflow encountered\n"); + printk(KERN_INFO "%s Rx Overflow encountered\n", __FUNCTION__); + ehci_writel(ehci, cmd | CMD_RUN, &ehci->regs->command); + status &= ~STS_RX_OVERFLOW; + udelay(5); + } + #undef STS_RX_OVERFLOW - /* INT, ERR, and IAA interrupt rates can be throttled */ +#endif /* CONFIG_MACH_AR934x */ /* normal [4.15.1.2] or error [4.15.1.1] completion */ if (likely ((status & (STS_INT|STS_ERR)) != 0)) { @@ -795,12 +845,12 @@ ehci->reset_done[i] == 0)) continue; - /* start 20 msec resume signaling from this port, - * and make khubd collect PORT_STAT_C_SUSPEND to - * stop that signaling. Use 5 ms extra for safety, - * like usb_port_resume() does. + /* start USB_RESUME_TIMEOUT msec resume signaling from + * this port, and make hub_wq collect + * PORT_STAT_C_SUSPEND to stop that signaling. */ - ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); + ehci->reset_done[i] = jiffies + + msecs_to_jiffies(USB_RESUME_TIMEOUT); set_bit(i, &ehci->resuming_ports); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); usb_hcd_start_port_resume(&hcd->self, i); @@ -946,7 +996,7 @@ { struct ehci_hcd *ehci = hcd_to_ehci (hcd); unsigned long flags; - struct ehci_qh *qh, *tmp; + struct ehci_qh *qh; /* ASSERT: any requests/urbs are being unlinked */ /* ASSERT: nobody can be submitting urbs for this any more */ @@ -967,6 +1017,7 @@ goto idle_timeout; /* BUG_ON(!list_empty(&stream->free_list)); */ + reserve_release_iso_bandwidth(ehci, stream, -1); kfree(stream); goto done; } @@ -974,17 +1025,13 @@ qh->exception = 1; switch (qh->qh_state) { case QH_STATE_LINKED: - case QH_STATE_COMPLETING: - for (tmp = ehci->async->qh_next.qh; - tmp && tmp != qh; - tmp = tmp->qh_next.qh) - continue; - /* periodic qh self-unlinks on empty, and a COMPLETING qh - * may already be unlinked. - */ - if (tmp) + WARN_ON(!list_empty(&qh->qtd_list)); + if (usb_endpoint_type(&ep->desc) != USB_ENDPOINT_XFER_INT) start_unlink_async(ehci, qh); + else + start_unlink_intr(ehci, qh); /* FALL THROUGH */ + case QH_STATE_COMPLETING: /* already in unlinking */ case QH_STATE_UNLINK: /* wait for hw to finish? */ case QH_STATE_UNLINK_WAIT: idle_timeout: @@ -995,6 +1042,8 @@ if (qh->clearing_tt) goto idle_timeout; if (list_empty (&qh->qtd_list)) { + if (qh->ps.bw_uperiod) + reserve_release_intr_bandwidth(ehci, qh, -1); qh_destroy(ehci, qh); break; } @@ -1035,7 +1084,6 @@ * the toggle bit in the QH. */ if (qh) { - usb_settoggle(qh->dev, epnum, is_out, 0); if (!list_empty(&qh->qtd_list)) { WARN_ONCE(1, "clear_halt for a busy endpoint\n"); } else { @@ -1043,6 +1091,7 @@ * while the QH is active. Unlink it now; * re-linking will call qh_refresh(). */ + usb_settoggle(qh->ps.udev, epnum, is_out, 0); qh->exception = 1; if (eptype == USB_ENDPOINT_XFER_BULK) start_unlink_async(ehci, qh); @@ -1061,6 +1110,19 @@ /*-------------------------------------------------------------------------*/ +/* Device addition and removal */ + +static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + + spin_lock_irq(&ehci->lock); + drop_tt(udev); + spin_unlock_irq(&ehci->lock); +} + +/*-------------------------------------------------------------------------*/ + #ifdef CONFIG_PM /* suspend/resume, section 4.3 */ @@ -1088,12 +1150,20 @@ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); spin_unlock_irq(&ehci->lock); + synchronize_irq(hcd->irq); + + /* Check for race with a wakeup request */ + if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) { + ehci_resume(hcd, false); + return -EBUSY; + } + return 0; } EXPORT_SYMBOL_GPL(ehci_suspend); /* Returns 0 if power was preserved, 1 if power was lost */ -int ehci_resume(struct usb_hcd *hcd, bool hibernated) +int ehci_resume(struct usb_hcd *hcd, bool force_reset) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); @@ -1107,12 +1177,12 @@ return 0; /* Controller is dead */ /* - * If CF is still set and we aren't resuming from hibernation + * If CF is still set and reset isn't forced * then we maintained suspend power. * Just undo the effect of ehci_suspend(). */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF && - !hibernated) { + !force_reset) { int mask = INTR_MASK; ehci_prepare_ports_for_controller_resume(ehci); @@ -1171,7 +1241,7 @@ * generic hardware linkage */ .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, + .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, /* * basic lifecycle operations @@ -1204,6 +1274,11 @@ .bus_resume = ehci_bus_resume, .relinquish_port = ehci_relinquish_port, .port_handed_over = ehci_port_handed_over, + + /* + * device support + */ + .free_dev = ehci_remove_device, }; void ehci_init_driver(struct hc_driver *drv, @@ -1216,6 +1291,8 @@ drv->hcd_priv_size += over->extra_priv_size; if (over->reset) drv->reset = over->reset; + if (over->port_power) + drv->port_power = over->port_power; } } EXPORT_SYMBOL_GPL(ehci_init_driver); @@ -1226,11 +1303,6 @@ MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_LICENSE ("GPL"); -#ifdef CONFIG_USB_EHCI_FSL -#include "ehci-fsl.c" -#define PLATFORM_DRIVER ehci_fsl_driver -#endif - #ifdef CONFIG_USB_EHCI_SH #include "ehci-sh.c" #define PLATFORM_DRIVER ehci_hcd_sh_driver @@ -1251,16 +1323,6 @@ #define XILINX_OF_PLATFORM_DRIVER ehci_hcd_xilinx_of_driver #endif -#ifdef CONFIG_USB_W90X900_EHCI -#include "ehci-w90x900.c" -#define PLATFORM_DRIVER ehci_hcd_w90x900_driver -#endif - -#ifdef CONFIG_USB_OCTEON_EHCI -#include "ehci-octeon.c" -#define PLATFORM_DRIVER ehci_octeon_driver -#endif - #ifdef CONFIG_TILE_USB #include "ehci-tilegx.c" #define PLATFORM_DRIVER ehci_hcd_tilegx_driver @@ -1271,11 +1333,6 @@ #define PLATFORM_DRIVER ehci_hcd_msp_driver #endif -#ifdef CONFIG_USB_EHCI_TEGRA -#include "ehci-tegra.c" -#define PLATFORM_DRIVER tegra_ehci_driver -#endif - #ifdef CONFIG_SPARC_LEON #include "ehci-grlib.c" #define PLATFORM_DRIVER ehci_grlib_driver @@ -1310,7 +1367,7 @@ sizeof(struct ehci_qh), sizeof(struct ehci_qtd), sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); -#ifdef DEBUG +#ifdef CONFIG_DYNAMIC_DEBUG ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root); if (!ehci_debug_root) { retval = -ENOENT; @@ -1359,7 +1416,7 @@ platform_driver_unregister(&PLATFORM_DRIVER); clean0: #endif -#ifdef DEBUG +#ifdef CONFIG_DYNAMIC_DEBUG debugfs_remove(ehci_debug_root); ehci_debug_root = NULL; err_debug: @@ -1383,7 +1440,7 @@ #ifdef PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); #endif -#ifdef DEBUG +#ifdef CONFIG_DYNAMIC_DEBUG debugfs_remove(ehci_debug_root); #endif clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);