diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/host/ehci-pci.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (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.c | 81 |
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 | ||
351 | static 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 | |||
358 | static 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 | |||
313 | static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) | 371 | static 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)) |