diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1f7d35b3a937..bf7da58b5751 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -183,7 +183,11 @@ int xhci_reset(struct xhci_hcd *xhci) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Reset the HC"); command = readl(&xhci->op_regs->command); +#ifdef CONFIG_USB_DWC3_OTG + command |= CMD_LRESET; +#else command |= CMD_RESET; +#endif writel(command, &xhci->op_regs->command); /* Existing Intel xHCI controllers require a delay of 1 mS, @@ -197,7 +201,12 @@ int xhci_reset(struct xhci_hcd *xhci) udelay(1000); ret = xhci_handshake(&xhci->op_regs->command, - CMD_RESET, 0, 10 * 1000 * 1000); +#ifdef CONFIG_USB_DWC3_OTG + CMD_LRESET, +#else + CMD_RESET, +#endif + 0, 10 * 1000 * 1000); if (ret) return ret; @@ -718,6 +727,12 @@ static void xhci_stop(struct usb_hcd *hcd) /* Only halt host and free memory after both hcds are removed */ if (!usb_hcd_is_primary_hcd(hcd)) { + /* Remove shared_hcd if no otg ports are present */ + if (!hcd->self.otg_port) { + /* usb core will free this hcd shortly, unset pointer */ + xhci->shared_hcd = NULL; + } + mutex_unlock(&xhci->mutex); return; } @@ -1670,8 +1685,21 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) goto err_giveback; } + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; + ep_ring = xhci_urb_to_transfer_ring(xhci, urb); + if (!ep_ring) { + ret = -EINVAL; + goto done; + } + + /* Delete the stream timer */ + if ((xhci->quirks & XHCI_STREAM_QUIRK) && (urb->stream_id > 0)) + del_timer(&ep_ring->stream_timer); + i = urb_priv->num_tds_done; if (i < urb_priv->num_tds) + xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Cancel URB %p, dev %s, ep 0x%x, " "starting at offset 0x%llx", |