aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-pci.c')
-rw-r--r--drivers/usb/host/ehci-pci.c132
1 files changed, 49 insertions, 83 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 2cb7d370c4ef..dabb20494826 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -18,9 +18,18 @@
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */ 19 */
20 20
21#ifndef CONFIG_PCI 21#include <linux/kernel.h>
22#error "This file is PCI bus glue. CONFIG_PCI must be defined." 22#include <linux/module.h>
23#endif 23#include <linux/pci.h>
24#include <linux/usb.h>
25#include <linux/usb/hcd.h>
26
27#include "ehci.h"
28#include "pci-quirks.h"
29
30#define DRIVER_DESC "EHCI PCI platform driver"
31
32static const char hcd_name[] = "ehci-pci";
24 33
25/* defined here to avoid adding to pci_ids.h for single instance use */ 34/* defined here to avoid adding to pci_ids.h for single instance use */
26#define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70 35#define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70
@@ -103,7 +112,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
103 } 112 }
104 break; 113 break;
105 case PCI_VENDOR_ID_INTEL: 114 case PCI_VENDOR_ID_INTEL:
106 ehci->fs_i_thresh = 1;
107 if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) 115 if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB)
108 hcd->has_tt = 1; 116 hcd->has_tt = 1;
109 break; 117 break;
@@ -203,11 +211,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
203 break; 211 break;
204 case PCI_VENDOR_ID_INTEL: 212 case PCI_VENDOR_ID_INTEL:
205 ehci->need_io_watchdog = 0; 213 ehci->need_io_watchdog = 0;
206 if (pdev->device == 0x0806 || pdev->device == 0x0811
207 || pdev->device == 0x0829) {
208 ehci_info(ehci, "disable lpm for langwell/penwell\n");
209 ehci->has_lpm = 0;
210 }
211 break; 214 break;
212 case PCI_VENDOR_ID_NVIDIA: 215 case PCI_VENDOR_ID_NVIDIA:
213 switch (pdev->device) { 216 switch (pdev->device) {
@@ -217,8 +220,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
217 * devices with PPCD enabled. 220 * devices with PPCD enabled.
218 */ 221 */
219 case 0x0d9d: 222 case 0x0d9d:
220 ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89"); 223 ehci_info(ehci, "disable ppcd for nvidia mcp89\n");
221 ehci->has_lpm = 0;
222 ehci->has_ppcd = 0; 224 ehci->has_ppcd = 0;
223 ehci->command &= ~CMD_PPCEE; 225 ehci->command &= ~CMD_PPCEE;
224 break; 226 break;
@@ -304,7 +306,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
304 ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); 306 ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
305#endif 307#endif
306 308
307 ehci_port_power(ehci, 1);
308 retval = ehci_pci_reinit(ehci, pdev); 309 retval = ehci_pci_reinit(ehci, pdev);
309done: 310done:
310 return retval; 311 return retval;
@@ -323,18 +324,14 @@ done:
323 * Also they depend on separate root hub suspend/resume. 324 * Also they depend on separate root hub suspend/resume.
324 */ 325 */
325 326
326static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
327{
328 return ehci_suspend(hcd, do_wakeup);
329}
330
331static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) 327static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev)
332{ 328{
333 return pdev->class == PCI_CLASS_SERIAL_USB_EHCI && 329 return pdev->class == PCI_CLASS_SERIAL_USB_EHCI &&
334 pdev->vendor == PCI_VENDOR_ID_INTEL && 330 pdev->vendor == PCI_VENDOR_ID_INTEL &&
335 (pdev->device == 0x1E26 || 331 (pdev->device == 0x1E26 ||
336 pdev->device == 0x8C2D || 332 pdev->device == 0x8C2D ||
337 pdev->device == 0x8C26); 333 pdev->device == 0x8C26 ||
334 pdev->device == 0x9C26);
338} 335}
339 336
340static void ehci_enable_xhci_companion(void) 337static void ehci_enable_xhci_companion(void)
@@ -378,76 +375,17 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
378 (void) ehci_pci_reinit(ehci, pdev); 375 (void) ehci_pci_reinit(ehci, pdev);
379 return 0; 376 return 0;
380} 377}
381#endif
382 378
383static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev) 379#else
384{
385 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
386 int rc = 0;
387
388 if (!udev->parent) /* udev is root hub itself, impossible */
389 rc = -1;
390 /* we only support lpm device connected to root hub yet */
391 if (ehci->has_lpm && !udev->parent->parent) {
392 rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
393 if (!rc)
394 rc = ehci_lpm_check(ehci, udev->portnum);
395 }
396 return rc;
397}
398 380
399static const struct hc_driver ehci_pci_hc_driver = { 381#define ehci_suspend NULL
400 .description = hcd_name, 382#define ehci_pci_resume NULL
401 .product_desc = "EHCI Host Controller", 383#endif /* CONFIG_PM */
402 .hcd_priv_size = sizeof(struct ehci_hcd),
403 384
404 /* 385static struct hc_driver __read_mostly ehci_pci_hc_driver;
405 * generic hardware linkage
406 */
407 .irq = ehci_irq,
408 .flags = HCD_MEMORY | HCD_USB2,
409 386
410 /* 387static const struct ehci_driver_overrides pci_overrides __initdata = {
411 * basic lifecycle operations
412 */
413 .reset = ehci_pci_setup, 388 .reset = ehci_pci_setup,
414 .start = ehci_run,
415#ifdef CONFIG_PM
416 .pci_suspend = ehci_pci_suspend,
417 .pci_resume = ehci_pci_resume,
418#endif
419 .stop = ehci_stop,
420 .shutdown = ehci_shutdown,
421
422 /*
423 * managing i/o requests and associated device resources
424 */
425 .urb_enqueue = ehci_urb_enqueue,
426 .urb_dequeue = ehci_urb_dequeue,
427 .endpoint_disable = ehci_endpoint_disable,
428 .endpoint_reset = ehci_endpoint_reset,
429
430 /*
431 * scheduling support
432 */
433 .get_frame_number = ehci_get_frame,
434
435 /*
436 * root hub support
437 */
438 .hub_status_data = ehci_hub_status_data,
439 .hub_control = ehci_hub_control,
440 .bus_suspend = ehci_bus_suspend,
441 .bus_resume = ehci_bus_resume,
442 .relinquish_port = ehci_relinquish_port,
443 .port_handed_over = ehci_port_handed_over,
444
445 /*
446 * call back when device connected and addressed
447 */
448 .update_device = ehci_update_device,
449
450 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
451}; 389};
452 390
453/*-------------------------------------------------------------------------*/ 391/*-------------------------------------------------------------------------*/
@@ -480,3 +418,31 @@ static struct pci_driver ehci_pci_driver = {
480 }, 418 },
481#endif 419#endif
482}; 420};
421
422static int __init ehci_pci_init(void)
423{
424 if (usb_disabled())
425 return -ENODEV;
426
427 pr_info("%s: " DRIVER_DESC "\n", hcd_name);
428
429 ehci_init_driver(&ehci_pci_hc_driver, &pci_overrides);
430
431 /* Entries for the PCI suspend/resume callbacks are special */
432 ehci_pci_hc_driver.pci_suspend = ehci_suspend;
433 ehci_pci_hc_driver.pci_resume = ehci_pci_resume;
434
435 return pci_register_driver(&ehci_pci_driver);
436}
437module_init(ehci_pci_init);
438
439static void __exit ehci_pci_cleanup(void)
440{
441 pci_unregister_driver(&ehci_pci_driver);
442}
443module_exit(ehci_pci_cleanup);
444
445MODULE_DESCRIPTION(DRIVER_DESC);
446MODULE_AUTHOR("David Brownell");
447MODULE_AUTHOR("Alan Stern");
448MODULE_LICENSE("GPL");