aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-05-28 21:25:34 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-05-28 21:25:34 -0400
commit1730ff27b14dcb39fd50dec3fa90166cc4cd30d7 (patch)
treeba83298752e174c785bb2836826ce09eaad2b2f9 /drivers/usb
parent61d5b3d65cf9e75224ca4401043279f91460d1df (diff)
parentc3897aa5386faba77e5bbdf94902a1658d3a5b11 (diff)
Merge tag 'for-usb-linus-2013-05-24' of git://git.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus
Sarah writes: xhci: Misc bug fixes for 3.10. Hi Greg, Here's four xHCI bug fixes that should be queued for 3.10. The first two are generic bug fixes, and have been in my queue for a while because I've been doing the OPW internship coordination. I suspect you'll be seeing more pull requests from me now that the intern selection process is almost over. :) The last two patches fix a nasty kernel crash on resume from S3 for TI hosts that have the compliance mode quirk. Tony has confirmed that the patches fix the issue on the effected systems. All four patches are marked for stable. Sarah Sharp
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-mem.c10
-rw-r--r--drivers/usb/host/xhci-pci.c8
-rw-r--r--drivers/usb/host/xhci.c16
-rw-r--r--drivers/usb/host/xhci.h3
4 files changed, 31 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2cfc465925bd..fbf75e57628b 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1827,6 +1827,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
1827 } 1827 }
1828 spin_unlock_irqrestore(&xhci->lock, flags); 1828 spin_unlock_irqrestore(&xhci->lock, flags);
1829 1829
1830 if (!xhci->rh_bw)
1831 goto no_bw;
1832
1830 num_ports = HCS_MAX_PORTS(xhci->hcs_params1); 1833 num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
1831 for (i = 0; i < num_ports; i++) { 1834 for (i = 0; i < num_ports; i++) {
1832 struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; 1835 struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
@@ -1845,6 +1848,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
1845 } 1848 }
1846 } 1849 }
1847 1850
1851no_bw:
1848 xhci->num_usb2_ports = 0; 1852 xhci->num_usb2_ports = 0;
1849 xhci->num_usb3_ports = 0; 1853 xhci->num_usb3_ports = 0;
1850 xhci->num_active_eps = 0; 1854 xhci->num_active_eps = 0;
@@ -2256,6 +2260,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
2256 u32 page_size, temp; 2260 u32 page_size, temp;
2257 int i; 2261 int i;
2258 2262
2263 INIT_LIST_HEAD(&xhci->lpm_failed_devs);
2264 INIT_LIST_HEAD(&xhci->cancel_cmd_list);
2265
2259 page_size = xhci_readl(xhci, &xhci->op_regs->page_size); 2266 page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
2260 xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size); 2267 xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
2261 for (i = 0; i < 16; i++) { 2268 for (i = 0; i < 16; i++) {
@@ -2334,7 +2341,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
2334 xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags); 2341 xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
2335 if (!xhci->cmd_ring) 2342 if (!xhci->cmd_ring)
2336 goto fail; 2343 goto fail;
2337 INIT_LIST_HEAD(&xhci->cancel_cmd_list);
2338 xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); 2344 xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
2339 xhci_dbg(xhci, "First segment DMA is 0x%llx\n", 2345 xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
2340 (unsigned long long)xhci->cmd_ring->first_seg->dma); 2346 (unsigned long long)xhci->cmd_ring->first_seg->dma);
@@ -2445,8 +2451,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
2445 if (xhci_setup_port_arrays(xhci, flags)) 2451 if (xhci_setup_port_arrays(xhci, flags))
2446 goto fail; 2452 goto fail;
2447 2453
2448 INIT_LIST_HEAD(&xhci->lpm_failed_devs);
2449
2450 /* Enable USB 3.0 device notifications for function remote wake, which 2454 /* Enable USB 3.0 device notifications for function remote wake, which
2451 * is necessary for allowing USB 3.0 devices to do remote wakeup from 2455 * is necessary for allowing USB 3.0 devices to do remote wakeup from
2452 * U3 (device suspend). 2456 * U3 (device suspend).
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 1a30c380043c..cc24e39b97d5 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -221,6 +221,14 @@ static void xhci_pci_remove(struct pci_dev *dev)
221static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) 221static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
222{ 222{
223 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 223 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
224 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
225
226 /*
227 * Systems with the TI redriver that loses port status change events
228 * need to have the registers polled during D3, so avoid D3cold.
229 */
230 if (xhci_compliance_mode_recovery_timer_quirk_check())
231 pdev->no_d3cold = true;
224 232
225 return xhci_suspend(xhci); 233 return xhci_suspend(xhci);
226} 234}
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index b4aa79d154b2..d8f640b12dd9 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -466,7 +466,7 @@ static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
466 * Systems: 466 * Systems:
467 * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820 467 * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
468 */ 468 */
469static bool compliance_mode_recovery_timer_quirk_check(void) 469bool xhci_compliance_mode_recovery_timer_quirk_check(void)
470{ 470{
471 const char *dmi_product_name, *dmi_sys_vendor; 471 const char *dmi_product_name, *dmi_sys_vendor;
472 472
@@ -517,7 +517,7 @@ int xhci_init(struct usb_hcd *hcd)
517 xhci_dbg(xhci, "Finished xhci_init\n"); 517 xhci_dbg(xhci, "Finished xhci_init\n");
518 518
519 /* Initializing Compliance Mode Recovery Data If Needed */ 519 /* Initializing Compliance Mode Recovery Data If Needed */
520 if (compliance_mode_recovery_timer_quirk_check()) { 520 if (xhci_compliance_mode_recovery_timer_quirk_check()) {
521 xhci->quirks |= XHCI_COMP_MODE_QUIRK; 521 xhci->quirks |= XHCI_COMP_MODE_QUIRK;
522 compliance_mode_recovery_timer_init(xhci); 522 compliance_mode_recovery_timer_init(xhci);
523 } 523 }
@@ -956,6 +956,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
956 struct usb_hcd *hcd = xhci_to_hcd(xhci); 956 struct usb_hcd *hcd = xhci_to_hcd(xhci);
957 struct usb_hcd *secondary_hcd; 957 struct usb_hcd *secondary_hcd;
958 int retval = 0; 958 int retval = 0;
959 bool comp_timer_running = false;
959 960
960 /* Wait a bit if either of the roothubs need to settle from the 961 /* Wait a bit if either of the roothubs need to settle from the
961 * transition into bus suspend. 962 * transition into bus suspend.
@@ -993,6 +994,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
993 994
994 /* If restore operation fails, re-initialize the HC during resume */ 995 /* If restore operation fails, re-initialize the HC during resume */
995 if ((temp & STS_SRE) || hibernated) { 996 if ((temp & STS_SRE) || hibernated) {
997
998 if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
999 !(xhci_all_ports_seen_u0(xhci))) {
1000 del_timer_sync(&xhci->comp_mode_recovery_timer);
1001 xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
1002 }
1003
996 /* Let the USB core know _both_ roothubs lost power. */ 1004 /* Let the USB core know _both_ roothubs lost power. */
997 usb_root_hub_lost_power(xhci->main_hcd->self.root_hub); 1005 usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
998 usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub); 1006 usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
@@ -1035,6 +1043,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
1035 retval = xhci_init(hcd->primary_hcd); 1043 retval = xhci_init(hcd->primary_hcd);
1036 if (retval) 1044 if (retval)
1037 return retval; 1045 return retval;
1046 comp_timer_running = true;
1047
1038 xhci_dbg(xhci, "Start the primary HCD\n"); 1048 xhci_dbg(xhci, "Start the primary HCD\n");
1039 retval = xhci_run(hcd->primary_hcd); 1049 retval = xhci_run(hcd->primary_hcd);
1040 if (!retval) { 1050 if (!retval) {
@@ -1076,7 +1086,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
1076 * to suffer the Compliance Mode issue again. It doesn't matter if 1086 * to suffer the Compliance Mode issue again. It doesn't matter if
1077 * ports have entered previously to U0 before system's suspension. 1087 * ports have entered previously to U0 before system's suspension.
1078 */ 1088 */
1079 if (xhci->quirks & XHCI_COMP_MODE_QUIRK) 1089 if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
1080 compliance_mode_recovery_timer_init(xhci); 1090 compliance_mode_recovery_timer_init(xhci);
1081 1091
1082 /* Re-enable port polling. */ 1092 /* Re-enable port polling. */
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 29c978e37135..77600cefcaf1 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1853,4 +1853,7 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
1853struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); 1853struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
1854struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); 1854struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
1855 1855
1856/* xHCI quirks */
1857bool xhci_compliance_mode_recovery_timer_quirk_check(void);
1858
1856#endif /* __LINUX_XHCI_HCD_H */ 1859#endif /* __LINUX_XHCI_HCD_H */