diff options
-rw-r--r-- | drivers/usb/host/xhci-mtk-sch.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mtk.c | 23 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 56 | ||||
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 1 |
7 files changed, 84 insertions, 29 deletions
diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index c30de7c39f44..73f763c4f5f5 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c | |||
@@ -275,8 +275,9 @@ static bool need_bw_sch(struct usb_host_endpoint *ep, | |||
275 | return false; | 275 | return false; |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * for LS & FS periodic endpoints which its device don't attach | 278 | * for LS & FS periodic endpoints which its device is not behind |
279 | * to TT are also ignored, root-hub will schedule them directly | 279 | * a TT are also ignored, root-hub will schedule them directly, |
280 | * but need set @bpkts field of endpoint context to 1. | ||
280 | */ | 281 | */ |
281 | if (is_fs_or_ls(speed) && !has_tt) | 282 | if (is_fs_or_ls(speed) && !has_tt) |
282 | return false; | 283 | return false; |
@@ -339,8 +340,17 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, | |||
339 | GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)), | 340 | GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)), |
340 | usb_endpoint_dir_in(&ep->desc), ep); | 341 | usb_endpoint_dir_in(&ep->desc), ep); |
341 | 342 | ||
342 | if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) | 343 | if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) { |
344 | /* | ||
345 | * set @bpkts to 1 if it is LS or FS periodic endpoint, and its | ||
346 | * device does not connected through an external HS hub | ||
347 | */ | ||
348 | if (usb_endpoint_xfer_int(&ep->desc) | ||
349 | || usb_endpoint_xfer_isoc(&ep->desc)) | ||
350 | ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(1)); | ||
351 | |||
343 | return 0; | 352 | return 0; |
353 | } | ||
344 | 354 | ||
345 | bw_index = get_bw_index(xhci, udev, ep); | 355 | bw_index = get_bw_index(xhci, udev, ep); |
346 | sch_bw = &sch_array[bw_index]; | 356 | sch_bw = &sch_array[bw_index]; |
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index c9ab6a44c34a..9532f5aef71b 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c | |||
@@ -696,9 +696,24 @@ static int xhci_mtk_remove(struct platform_device *dev) | |||
696 | } | 696 | } |
697 | 697 | ||
698 | #ifdef CONFIG_PM_SLEEP | 698 | #ifdef CONFIG_PM_SLEEP |
699 | /* | ||
700 | * if ip sleep fails, and all clocks are disabled, access register will hang | ||
701 | * AHB bus, so stop polling roothubs to avoid regs access on bus suspend. | ||
702 | * and no need to check whether ip sleep failed or not; this will cause SPM | ||
703 | * to wake up system immediately after system suspend complete if ip sleep | ||
704 | * fails, it is what we wanted. | ||
705 | */ | ||
699 | static int xhci_mtk_suspend(struct device *dev) | 706 | static int xhci_mtk_suspend(struct device *dev) |
700 | { | 707 | { |
701 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); | 708 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); |
709 | struct usb_hcd *hcd = mtk->hcd; | ||
710 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
711 | |||
712 | xhci_dbg(xhci, "%s: stop port polling\n", __func__); | ||
713 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); | ||
714 | del_timer_sync(&hcd->rh_timer); | ||
715 | clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); | ||
716 | del_timer_sync(&xhci->shared_hcd->rh_timer); | ||
702 | 717 | ||
703 | xhci_mtk_host_disable(mtk); | 718 | xhci_mtk_host_disable(mtk); |
704 | xhci_mtk_phy_power_off(mtk); | 719 | xhci_mtk_phy_power_off(mtk); |
@@ -710,11 +725,19 @@ static int xhci_mtk_suspend(struct device *dev) | |||
710 | static int xhci_mtk_resume(struct device *dev) | 725 | static int xhci_mtk_resume(struct device *dev) |
711 | { | 726 | { |
712 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); | 727 | struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); |
728 | struct usb_hcd *hcd = mtk->hcd; | ||
729 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
713 | 730 | ||
714 | usb_wakeup_disable(mtk); | 731 | usb_wakeup_disable(mtk); |
715 | xhci_mtk_clks_enable(mtk); | 732 | xhci_mtk_clks_enable(mtk); |
716 | xhci_mtk_phy_power_on(mtk); | 733 | xhci_mtk_phy_power_on(mtk); |
717 | xhci_mtk_host_enable(mtk); | 734 | xhci_mtk_host_enable(mtk); |
735 | |||
736 | xhci_dbg(xhci, "%s: restart port polling\n", __func__); | ||
737 | set_bit(HCD_FLAG_POLL_RH, &hcd->flags); | ||
738 | usb_hcd_poll_rh_status(hcd); | ||
739 | set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); | ||
740 | usb_hcd_poll_rh_status(xhci->shared_hcd); | ||
718 | return 0; | 741 | return 0; |
719 | } | 742 | } |
720 | 743 | ||
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 58c43ed7ff3b..f0640b7a1c42 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -28,7 +28,9 @@ | |||
28 | #include "xhci.h" | 28 | #include "xhci.h" |
29 | #include "xhci-trace.h" | 29 | #include "xhci-trace.h" |
30 | 30 | ||
31 | #define PORT2_SSIC_CONFIG_REG2 0x883c | 31 | #define SSIC_PORT_NUM 2 |
32 | #define SSIC_PORT_CFG2 0x880c | ||
33 | #define SSIC_PORT_CFG2_OFFSET 0x30 | ||
32 | #define PROG_DONE (1 << 30) | 34 | #define PROG_DONE (1 << 30) |
33 | #define SSIC_PORT_UNUSED (1 << 31) | 35 | #define SSIC_PORT_UNUSED (1 << 31) |
34 | 36 | ||
@@ -45,6 +47,7 @@ | |||
45 | #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 | 47 | #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 |
46 | #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f | 48 | #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f |
47 | #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f | 49 | #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f |
50 | #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8 | ||
48 | 51 | ||
49 | static const char hcd_name[] = "xhci_hcd"; | 52 | static const char hcd_name[] = "xhci_hcd"; |
50 | 53 | ||
@@ -151,9 +154,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
151 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | 154 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && |
152 | (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || | 155 | (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || |
153 | pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || | 156 | pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || |
154 | pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) { | 157 | pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || |
158 | pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) { | ||
155 | xhci->quirks |= XHCI_PME_STUCK_QUIRK; | 159 | xhci->quirks |= XHCI_PME_STUCK_QUIRK; |
156 | } | 160 | } |
161 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | ||
162 | pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { | ||
163 | xhci->quirks |= XHCI_SSIC_PORT_UNUSED; | ||
164 | } | ||
157 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 165 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
158 | pdev->device == PCI_DEVICE_ID_EJ168) { | 166 | pdev->device == PCI_DEVICE_ID_EJ168) { |
159 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 167 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
@@ -312,22 +320,20 @@ static void xhci_pci_remove(struct pci_dev *dev) | |||
312 | * SSIC PORT need to be marked as "unused" before putting xHCI | 320 | * SSIC PORT need to be marked as "unused" before putting xHCI |
313 | * into D3. After D3 exit, the SSIC port need to be marked as "used". | 321 | * into D3. After D3 exit, the SSIC port need to be marked as "used". |
314 | * Without this change, xHCI might not enter D3 state. | 322 | * Without this change, xHCI might not enter D3 state. |
315 | * Make sure PME works on some Intel xHCI controllers by writing 1 to clear | ||
316 | * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 | ||
317 | */ | 323 | */ |
318 | static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend) | 324 | static void xhci_ssic_port_unused_quirk(struct usb_hcd *hcd, bool suspend) |
319 | { | 325 | { |
320 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 326 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
321 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
322 | u32 val; | 327 | u32 val; |
323 | void __iomem *reg; | 328 | void __iomem *reg; |
329 | int i; | ||
324 | 330 | ||
325 | if (pdev->vendor == PCI_VENDOR_ID_INTEL && | 331 | for (i = 0; i < SSIC_PORT_NUM; i++) { |
326 | pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { | 332 | reg = (void __iomem *) xhci->cap_regs + |
327 | 333 | SSIC_PORT_CFG2 + | |
328 | reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2; | 334 | i * SSIC_PORT_CFG2_OFFSET; |
329 | 335 | ||
330 | /* Notify SSIC that SSIC profile programming is not done */ | 336 | /* Notify SSIC that SSIC profile programming is not done. */ |
331 | val = readl(reg) & ~PROG_DONE; | 337 | val = readl(reg) & ~PROG_DONE; |
332 | writel(val, reg); | 338 | writel(val, reg); |
333 | 339 | ||
@@ -344,6 +350,17 @@ static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend) | |||
344 | writel(val, reg); | 350 | writel(val, reg); |
345 | readl(reg); | 351 | readl(reg); |
346 | } | 352 | } |
353 | } | ||
354 | |||
355 | /* | ||
356 | * Make sure PME works on some Intel xHCI controllers by writing 1 to clear | ||
357 | * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 | ||
358 | */ | ||
359 | static void xhci_pme_quirk(struct usb_hcd *hcd) | ||
360 | { | ||
361 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
362 | void __iomem *reg; | ||
363 | u32 val; | ||
347 | 364 | ||
348 | reg = (void __iomem *) xhci->cap_regs + 0x80a4; | 365 | reg = (void __iomem *) xhci->cap_regs + 0x80a4; |
349 | val = readl(reg); | 366 | val = readl(reg); |
@@ -355,6 +372,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
355 | { | 372 | { |
356 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 373 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
357 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 374 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
375 | int ret; | ||
358 | 376 | ||
359 | /* | 377 | /* |
360 | * Systems with the TI redriver that loses port status change events | 378 | * Systems with the TI redriver that loses port status change events |
@@ -364,9 +382,16 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
364 | pdev->no_d3cold = true; | 382 | pdev->no_d3cold = true; |
365 | 383 | ||
366 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) | 384 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) |
367 | xhci_pme_quirk(hcd, true); | 385 | xhci_pme_quirk(hcd); |
386 | |||
387 | if (xhci->quirks & XHCI_SSIC_PORT_UNUSED) | ||
388 | xhci_ssic_port_unused_quirk(hcd, true); | ||
368 | 389 | ||
369 | return xhci_suspend(xhci, do_wakeup); | 390 | ret = xhci_suspend(xhci, do_wakeup); |
391 | if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED)) | ||
392 | xhci_ssic_port_unused_quirk(hcd, false); | ||
393 | |||
394 | return ret; | ||
370 | } | 395 | } |
371 | 396 | ||
372 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 397 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) |
@@ -396,8 +421,11 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) | |||
396 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) | 421 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) |
397 | usb_enable_intel_xhci_ports(pdev); | 422 | usb_enable_intel_xhci_ports(pdev); |
398 | 423 | ||
424 | if (xhci->quirks & XHCI_SSIC_PORT_UNUSED) | ||
425 | xhci_ssic_port_unused_quirk(hcd, false); | ||
426 | |||
399 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) | 427 | if (xhci->quirks & XHCI_PME_STUCK_QUIRK) |
400 | xhci_pme_quirk(hcd, false); | 428 | xhci_pme_quirk(hcd); |
401 | 429 | ||
402 | retval = xhci_resume(xhci, hibernated); | 430 | retval = xhci_resume(xhci, hibernated); |
403 | return retval; | 431 | return retval; |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 770b6b088797..d39d6bf1d090 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -184,7 +184,8 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
184 | struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); | 184 | struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); |
185 | 185 | ||
186 | /* Just copy data for now */ | 186 | /* Just copy data for now */ |
187 | *priv = *priv_match; | 187 | if (priv_match) |
188 | *priv = *priv_match; | ||
188 | } | 189 | } |
189 | 190 | ||
190 | if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_MARVELL_ARMADA)) { | 191 | if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_MARVELL_ARMADA)) { |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f1c21c40b4a6..3915657e6078 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2193,10 +2193,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
2193 | } | 2193 | } |
2194 | /* Fast path - was this the last TRB in the TD for this URB? */ | 2194 | /* Fast path - was this the last TRB in the TD for this URB? */ |
2195 | } else if (event_trb == td->last_trb) { | 2195 | } else if (event_trb == td->last_trb) { |
2196 | if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX) | ||
2197 | return finish_td(xhci, td, event_trb, event, ep, | ||
2198 | status, false); | ||
2199 | |||
2200 | if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { | 2196 | if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { |
2201 | td->urb->actual_length = | 2197 | td->urb->actual_length = |
2202 | td->urb->transfer_buffer_length - | 2198 | td->urb->transfer_buffer_length - |
@@ -2248,12 +2244,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
2248 | td->urb->actual_length += | 2244 | td->urb->actual_length += |
2249 | TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - | 2245 | TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - |
2250 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); | 2246 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |
2251 | |||
2252 | if (trb_comp_code == COMP_SHORT_TX) { | ||
2253 | xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n"); | ||
2254 | td->urb_length_set = true; | ||
2255 | return 0; | ||
2256 | } | ||
2257 | } | 2247 | } |
2258 | 2248 | ||
2259 | return finish_td(xhci, td, event_trb, event, ep, status, false); | 2249 | return finish_td(xhci, td, event_trb, event, ep, status, false); |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 26a44c0e969e..0c8087d3c313 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -1554,7 +1554,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1554 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, | 1554 | xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, |
1555 | "HW died, freeing TD."); | 1555 | "HW died, freeing TD."); |
1556 | urb_priv = urb->hcpriv; | 1556 | urb_priv = urb->hcpriv; |
1557 | for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { | 1557 | for (i = urb_priv->td_cnt; |
1558 | i < urb_priv->length && xhci->devs[urb->dev->slot_id]; | ||
1559 | i++) { | ||
1558 | td = urb_priv->td[i]; | 1560 | td = urb_priv->td[i]; |
1559 | if (!list_empty(&td->td_list)) | 1561 | if (!list_empty(&td->td_list)) |
1560 | list_del_init(&td->td_list); | 1562 | list_del_init(&td->td_list); |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9be7348872ba..cc651383ce5a 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1631,6 +1631,7 @@ struct xhci_hcd { | |||
1631 | #define XHCI_BROKEN_STREAMS (1 << 19) | 1631 | #define XHCI_BROKEN_STREAMS (1 << 19) |
1632 | #define XHCI_PME_STUCK_QUIRK (1 << 20) | 1632 | #define XHCI_PME_STUCK_QUIRK (1 << 20) |
1633 | #define XHCI_MTK_HOST (1 << 21) | 1633 | #define XHCI_MTK_HOST (1 << 21) |
1634 | #define XHCI_SSIC_PORT_UNUSED (1 << 22) | ||
1634 | unsigned int num_active_eps; | 1635 | unsigned int num_active_eps; |
1635 | unsigned int limit_active_eps; | 1636 | unsigned int limit_active_eps; |
1636 | /* There are two roothubs to keep track of bus suspend info for */ | 1637 | /* There are two roothubs to keep track of bus suspend info for */ |