diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 24 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 2 |
4 files changed, 32 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index ceea9f33491c..a10494c2f3c7 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -114,6 +114,10 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
114 | if (pdev->vendor == PCI_VENDOR_ID_NEC) | 114 | if (pdev->vendor == PCI_VENDOR_ID_NEC) |
115 | xhci->quirks |= XHCI_NEC_HOST; | 115 | xhci->quirks |= XHCI_NEC_HOST; |
116 | 116 | ||
117 | /* AMD PLL quirk */ | ||
118 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) | ||
119 | xhci->quirks |= XHCI_AMD_PLL_FIX; | ||
120 | |||
117 | /* Make sure the HC is halted. */ | 121 | /* Make sure the HC is halted. */ |
118 | retval = xhci_halt(xhci); | 122 | retval = xhci_halt(xhci); |
119 | if (retval) | 123 | if (retval) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b0b4cc3b8584..7437386a9a50 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -619,6 +619,13 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, | |||
619 | 619 | ||
620 | /* Only giveback urb when this is the last td in urb */ | 620 | /* Only giveback urb when this is the last td in urb */ |
621 | if (urb_priv->td_cnt == urb_priv->length) { | 621 | if (urb_priv->td_cnt == urb_priv->length) { |
622 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
623 | xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; | ||
624 | if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { | ||
625 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
626 | usb_amd_quirk_pll_enable(); | ||
627 | } | ||
628 | } | ||
622 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 629 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
623 | xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, urb); | 630 | xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, urb); |
624 | 631 | ||
@@ -1565,8 +1572,17 @@ td_cleanup: | |||
1565 | 1572 | ||
1566 | urb_priv->td_cnt++; | 1573 | urb_priv->td_cnt++; |
1567 | /* Giveback the urb when all the tds are completed */ | 1574 | /* Giveback the urb when all the tds are completed */ |
1568 | if (urb_priv->td_cnt == urb_priv->length) | 1575 | if (urb_priv->td_cnt == urb_priv->length) { |
1569 | ret = 1; | 1576 | ret = 1; |
1577 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
1578 | xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; | ||
1579 | if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs | ||
1580 | == 0) { | ||
1581 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
1582 | usb_amd_quirk_pll_enable(); | ||
1583 | } | ||
1584 | } | ||
1585 | } | ||
1570 | } | 1586 | } |
1571 | 1587 | ||
1572 | return ret; | 1588 | return ret; |
@@ -3153,6 +3169,12 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3153 | } | 3169 | } |
3154 | } | 3170 | } |
3155 | 3171 | ||
3172 | if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { | ||
3173 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
3174 | usb_amd_quirk_pll_disable(); | ||
3175 | } | ||
3176 | xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs++; | ||
3177 | |||
3156 | giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, | 3178 | giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, |
3157 | start_cycle, start_trb); | 3179 | start_cycle, start_trb); |
3158 | return 0; | 3180 | return 0; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c41358e4b8cc..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); |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index bdb78f51735e..ba1be6b7cc6d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | /* Code sharing between pci-quirks and xhci hcd */ | 31 | /* Code sharing between pci-quirks and xhci hcd */ |
32 | #include "xhci-ext-caps.h" | 32 | #include "xhci-ext-caps.h" |
33 | #include "pci-quirks.h" | ||
33 | 34 | ||
34 | /* xHCI PCI Configuration Registers */ | 35 | /* xHCI PCI Configuration Registers */ |
35 | #define XHCI_SBRN_OFFSET (0x60) | 36 | #define XHCI_SBRN_OFFSET (0x60) |
@@ -1279,6 +1280,7 @@ struct xhci_hcd { | |||
1279 | #define XHCI_LINK_TRB_QUIRK (1 << 0) | 1280 | #define XHCI_LINK_TRB_QUIRK (1 << 0) |
1280 | #define XHCI_RESET_EP_QUIRK (1 << 1) | 1281 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
1281 | #define XHCI_NEC_HOST (1 << 2) | 1282 | #define XHCI_NEC_HOST (1 << 2) |
1283 | #define XHCI_AMD_PLL_FIX (1 << 3) | ||
1282 | /* There are two roothubs to keep track of bus suspend info for */ | 1284 | /* There are two roothubs to keep track of bus suspend info for */ |
1283 | struct xhci_bus_state bus_state[2]; | 1285 | struct xhci_bus_state bus_state[2]; |
1284 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ | 1286 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ |