diff options
Diffstat (limited to 'drivers/usb/host/ehci-pci.c')
-rw-r--r-- | drivers/usb/host/ehci-pci.c | 132 |
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 | |||
32 | static 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); |
309 | done: | 310 | done: |
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 | ||
326 | static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | ||
327 | { | ||
328 | return ehci_suspend(hcd, do_wakeup); | ||
329 | } | ||
330 | |||
331 | static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) | 327 | static 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 | ||
340 | static void ehci_enable_xhci_companion(void) | 337 | static 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 | ||
383 | static 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 | ||
399 | static 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 | /* | 385 | static 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 | /* | 387 | static 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 | |||
422 | static 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 | } | ||
437 | module_init(ehci_pci_init); | ||
438 | |||
439 | static void __exit ehci_pci_cleanup(void) | ||
440 | { | ||
441 | pci_unregister_driver(&ehci_pci_driver); | ||
442 | } | ||
443 | module_exit(ehci_pci_cleanup); | ||
444 | |||
445 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
446 | MODULE_AUTHOR("David Brownell"); | ||
447 | MODULE_AUTHOR("Alan Stern"); | ||
448 | MODULE_LICENSE("GPL"); | ||