aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-pci.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/host/ehci-pci.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/host/ehci-pci.c')
-rw-r--r--drivers/usb/host/ehci-pci.c81
1 files changed, 79 insertions, 2 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index a1e8d273103f..1102ce65a3a9 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -22,6 +22,9 @@
22#error "This file is PCI bus glue. CONFIG_PCI must be defined." 22#error "This file is PCI bus glue. CONFIG_PCI must be defined."
23#endif 23#endif
24 24
25/* defined here to avoid adding to pci_ids.h for single instance use */
26#define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70
27
25/*-------------------------------------------------------------------------*/ 28/*-------------------------------------------------------------------------*/
26 29
27/* called after powerup, by probe or system-pm "wakeup" */ 30/* called after powerup, by probe or system-pm "wakeup" */
@@ -67,7 +70,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
67 70
68 ehci->caps = hcd->regs; 71 ehci->caps = hcd->regs;
69 ehci->regs = hcd->regs + 72 ehci->regs = hcd->regs +
70 HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); 73 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
71 74
72 dbg_hcs_params(ehci, "reset"); 75 dbg_hcs_params(ehci, "reset");
73 dbg_hcc_params(ehci, "reset"); 76 dbg_hcc_params(ehci, "reset");
@@ -103,6 +106,19 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
103 if (retval) 106 if (retval)
104 return retval; 107 return retval;
105 108
109 if ((pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x7808) ||
110 (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x4396)) {
111 /* EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may
112 * read/write memory space which does not belong to it when
113 * there is NULL pointer with T-bit set to 1 in the frame list
114 * table. To avoid the issue, the frame list link pointer
115 * should always contain a valid pointer to a inactive qh.
116 */
117 ehci->use_dummy_qh = 1;
118 ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI "
119 "dummy qh workaround\n");
120 }
121
106 /* data structure init */ 122 /* data structure init */
107 retval = ehci_init(hcd); 123 retval = ehci_init(hcd);
108 if (retval) 124 if (retval)
@@ -124,6 +140,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
124 ehci_info(ehci, "disable lpm for langwell/penwell\n"); 140 ehci_info(ehci, "disable lpm for langwell/penwell\n");
125 ehci->has_lpm = 0; 141 ehci->has_lpm = 0;
126 } 142 }
143 if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) {
144 hcd->has_tt = 1;
145 tdi_reset(ehci);
146 }
127 break; 147 break;
128 case PCI_VENDOR_ID_TDI: 148 case PCI_VENDOR_ID_TDI:
129 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { 149 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
@@ -132,6 +152,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
132 } 152 }
133 break; 153 break;
134 case PCI_VENDOR_ID_AMD: 154 case PCI_VENDOR_ID_AMD:
155 /* AMD PLL quirk */
156 if (usb_amd_find_chipset_info())
157 ehci->amd_pll_fix = 1;
135 /* AMD8111 EHCI doesn't work, according to AMD errata */ 158 /* AMD8111 EHCI doesn't work, according to AMD errata */
136 if (pdev->device == 0x7463) { 159 if (pdev->device == 0x7463) {
137 ehci_info(ehci, "ignoring AMD8111 (errata)\n"); 160 ehci_info(ehci, "ignoring AMD8111 (errata)\n");
@@ -148,6 +171,18 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
148 if (pdev->revision < 0xa4) 171 if (pdev->revision < 0xa4)
149 ehci->no_selective_suspend = 1; 172 ehci->no_selective_suspend = 1;
150 break; 173 break;
174
175 /* MCP89 chips on the MacBookAir3,1 give EPROTO when
176 * fetching device descriptors unless LPM is disabled.
177 * There are also intermittent problems enumerating
178 * devices with PPCD enabled.
179 */
180 case 0x0d9d:
181 ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89");
182 ehci->has_lpm = 0;
183 ehci->has_ppcd = 0;
184 ehci->command &= ~CMD_PPCEE;
185 break;
151 } 186 }
152 break; 187 break;
153 case PCI_VENDOR_ID_VIA: 188 case PCI_VENDOR_ID_VIA:
@@ -165,6 +200,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
165 } 200 }
166 break; 201 break;
167 case PCI_VENDOR_ID_ATI: 202 case PCI_VENDOR_ID_ATI:
203 /* AMD PLL quirk */
204 if (usb_amd_find_chipset_info())
205 ehci->amd_pll_fix = 1;
168 /* SB600 and old version of SB700 have a bug in EHCI controller, 206 /* SB600 and old version of SB700 have a bug in EHCI controller,
169 * which causes usb devices lose response in some cases. 207 * which causes usb devices lose response in some cases.
170 */ 208 */
@@ -296,8 +334,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
296 * mark HW unaccessible. The PM and USB cores make sure that 334 * mark HW unaccessible. The PM and USB cores make sure that
297 * the root hub is either suspended or stopped. 335 * the root hub is either suspended or stopped.
298 */ 336 */
299 spin_lock_irqsave (&ehci->lock, flags);
300 ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup); 337 ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup);
338 spin_lock_irqsave (&ehci->lock, flags);
301 ehci_writel(ehci, 0, &ehci->regs->intr_enable); 339 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
302 (void)ehci_readl(ehci, &ehci->regs->intr_enable); 340 (void)ehci_readl(ehci, &ehci->regs->intr_enable);
303 341
@@ -310,11 +348,50 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
310 return rc; 348 return rc;
311} 349}
312 350
351static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
352{
353 return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
354 pdev->vendor == PCI_VENDOR_ID_INTEL &&
355 pdev->device == 0x1E26;
356}
357
358static void ehci_enable_xhci_companion(void)
359{
360 struct pci_dev *companion = NULL;
361
362 /* The xHCI and EHCI controllers are not on the same PCI slot */
363 for_each_pci_dev(companion) {
364 if (!usb_is_intel_switchable_xhci(companion))
365 continue;
366 usb_enable_xhci_ports(companion);
367 return;
368 }
369}
370
313static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) 371static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
314{ 372{
315 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 373 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
316 struct pci_dev *pdev = to_pci_dev(hcd->self.controller); 374 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
317 375
376 /* The BIOS on systems with the Intel Panther Point chipset may or may
377 * not support xHCI natively. That means that during system resume, it
378 * may switch the ports back to EHCI so that users can use their
379 * keyboard to select a kernel from GRUB after resume from hibernate.
380 *
381 * The BIOS is supposed to remember whether the OS had xHCI ports
382 * enabled before resume, and switch the ports back to xHCI when the
383 * BIOS/OS semaphore is written, but we all know we can't trust BIOS
384 * writers.
385 *
386 * Unconditionally switch the ports back to xHCI after a system resume.
387 * We can't tell whether the EHCI or xHCI controller will be resumed
388 * first, so we have to do the port switchover in both drivers. Writing
389 * a '1' to the port switchover registers should have no effect if the
390 * port was already switched over.
391 */
392 if (usb_is_intel_switchable_ehci(pdev))
393 ehci_enable_xhci_companion();
394
318 // maybe restore FLADJ 395 // maybe restore FLADJ
319 396
320 if (time_before(jiffies, ehci->next_statechange)) 397 if (time_before(jiffies, ehci->next_statechange))