diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9a3645fd759b..81b976e45880 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -550,6 +550,9 @@ void xhci_stop(struct usb_hcd *hcd) | |||
550 | del_timer_sync(&xhci->event_ring_timer); | 550 | del_timer_sync(&xhci->event_ring_timer); |
551 | #endif | 551 | #endif |
552 | 552 | ||
553 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
554 | usb_amd_dev_put(); | ||
555 | |||
553 | xhci_dbg(xhci, "// Disabling event ring interrupts\n"); | 556 | xhci_dbg(xhci, "// Disabling event ring interrupts\n"); |
554 | temp = xhci_readl(xhci, &xhci->op_regs->status); | 557 | temp = xhci_readl(xhci, &xhci->op_regs->status); |
555 | xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); | 558 | xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); |
@@ -741,7 +744,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
741 | int retval; | 744 | int retval; |
742 | 745 | ||
743 | /* Wait a bit if either of the roothubs need to settle from the | 746 | /* Wait a bit if either of the roothubs need to settle from the |
744 | * transistion into bus suspend. | 747 | * transition into bus suspend. |
745 | */ | 748 | */ |
746 | if (time_before(jiffies, xhci->bus_state[0].next_statechange) || | 749 | if (time_before(jiffies, xhci->bus_state[0].next_statechange) || |
747 | time_before(jiffies, | 750 | time_before(jiffies, |
@@ -771,7 +774,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
771 | 774 | ||
772 | /* If restore operation fails, re-initialize the HC during resume */ | 775 | /* If restore operation fails, re-initialize the HC during resume */ |
773 | if ((temp & STS_SRE) || hibernated) { | 776 | if ((temp & STS_SRE) || hibernated) { |
774 | usb_root_hub_lost_power(hcd->self.root_hub); | 777 | /* Let the USB core know _both_ roothubs lost power. */ |
778 | usb_root_hub_lost_power(xhci->main_hcd->self.root_hub); | ||
779 | usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub); | ||
775 | 780 | ||
776 | xhci_dbg(xhci, "Stop HCD\n"); | 781 | xhci_dbg(xhci, "Stop HCD\n"); |
777 | xhci_halt(xhci); | 782 | xhci_halt(xhci); |
@@ -2072,7 +2077,7 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
2072 | return -EINVAL; | 2077 | return -EINVAL; |
2073 | } | 2078 | } |
2074 | vdev = xhci->devs[udev->slot_id]; | 2079 | vdev = xhci->devs[udev->slot_id]; |
2075 | /* Mark each endpoint as being in transistion, so | 2080 | /* Mark each endpoint as being in transition, so |
2076 | * xhci_urb_enqueue() will reject all URBs. | 2081 | * xhci_urb_enqueue() will reject all URBs. |
2077 | */ | 2082 | */ |
2078 | for (i = 0; i < num_eps; i++) { | 2083 | for (i = 0; i < num_eps; i++) { |
@@ -2386,10 +2391,18 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2386 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ | 2391 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ |
2387 | last_freed_endpoint = 1; | 2392 | last_freed_endpoint = 1; |
2388 | for (i = 1; i < 31; ++i) { | 2393 | for (i = 1; i < 31; ++i) { |
2389 | if (!virt_dev->eps[i].ring) | 2394 | struct xhci_virt_ep *ep = &virt_dev->eps[i]; |
2390 | continue; | 2395 | |
2391 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 2396 | if (ep->ep_state & EP_HAS_STREAMS) { |
2392 | last_freed_endpoint = i; | 2397 | xhci_free_stream_info(xhci, ep->stream_info); |
2398 | ep->stream_info = NULL; | ||
2399 | ep->ep_state &= ~EP_HAS_STREAMS; | ||
2400 | } | ||
2401 | |||
2402 | if (ep->ring) { | ||
2403 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | ||
2404 | last_freed_endpoint = i; | ||
2405 | } | ||
2393 | } | 2406 | } |
2394 | xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); | 2407 | xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); |
2395 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); | 2408 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); |