diff options
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index a4b12404ae08..544f7589912f 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -443,11 +443,16 @@ ohci_reboot (struct notifier_block *block, unsigned long code, void *null) | |||
443 | static int ohci_init (struct ohci_hcd *ohci) | 443 | static int ohci_init (struct ohci_hcd *ohci) |
444 | { | 444 | { |
445 | int ret; | 445 | int ret; |
446 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | ||
446 | 447 | ||
447 | disable (ohci); | 448 | disable (ohci); |
448 | ohci->regs = ohci_to_hcd(ohci)->regs; | 449 | ohci->regs = hcd->regs; |
449 | ohci->next_statechange = jiffies; | 450 | ohci->next_statechange = jiffies; |
450 | 451 | ||
452 | /* REVISIT this BIOS handshake is now moved into PCI "quirks", and | ||
453 | * was never needed for most non-PCI systems ... remove the code? | ||
454 | */ | ||
455 | |||
451 | #ifndef IR_DISABLE | 456 | #ifndef IR_DISABLE |
452 | /* SMM owns the HC? not for long! */ | 457 | /* SMM owns the HC? not for long! */ |
453 | if (!no_handshake && ohci_readl (ohci, | 458 | if (!no_handshake && ohci_readl (ohci, |
@@ -478,8 +483,10 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
478 | 483 | ||
479 | /* Disable HC interrupts */ | 484 | /* Disable HC interrupts */ |
480 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 485 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
481 | // flush the writes | 486 | |
482 | (void) ohci_readl (ohci, &ohci->regs->control); | 487 | /* flush the writes, and save key bits like RWC */ |
488 | if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC) | ||
489 | ohci->hc_control |= OHCI_CTRL_RWC; | ||
483 | 490 | ||
484 | /* Read the number of ports unless overridden */ | 491 | /* Read the number of ports unless overridden */ |
485 | if (ohci->num_ports == 0) | 492 | if (ohci->num_ports == 0) |
@@ -488,16 +495,19 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
488 | if (ohci->hcca) | 495 | if (ohci->hcca) |
489 | return 0; | 496 | return 0; |
490 | 497 | ||
491 | ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller, | 498 | ohci->hcca = dma_alloc_coherent (hcd->self.controller, |
492 | sizeof *ohci->hcca, &ohci->hcca_dma, 0); | 499 | sizeof *ohci->hcca, &ohci->hcca_dma, 0); |
493 | if (!ohci->hcca) | 500 | if (!ohci->hcca) |
494 | return -ENOMEM; | 501 | return -ENOMEM; |
495 | 502 | ||
496 | if ((ret = ohci_mem_init (ohci)) < 0) | 503 | if ((ret = ohci_mem_init (ohci)) < 0) |
497 | ohci_stop (ohci_to_hcd(ohci)); | 504 | ohci_stop (hcd); |
505 | else { | ||
506 | register_reboot_notifier (&ohci->reboot_notifier); | ||
507 | create_debug_files (ohci); | ||
508 | } | ||
498 | 509 | ||
499 | return ret; | 510 | return ret; |
500 | |||
501 | } | 511 | } |
502 | 512 | ||
503 | /*-------------------------------------------------------------------------*/ | 513 | /*-------------------------------------------------------------------------*/ |
@@ -510,6 +520,7 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
510 | { | 520 | { |
511 | u32 mask, temp; | 521 | u32 mask, temp; |
512 | int first = ohci->fminterval == 0; | 522 | int first = ohci->fminterval == 0; |
523 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | ||
513 | 524 | ||
514 | disable (ohci); | 525 | disable (ohci); |
515 | 526 | ||
@@ -525,18 +536,17 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
525 | /* also: power/overcurrent flags in roothub.a */ | 536 | /* also: power/overcurrent flags in roothub.a */ |
526 | } | 537 | } |
527 | 538 | ||
528 | /* Reset USB nearly "by the book". RemoteWakeupConnected | 539 | /* Reset USB nearly "by the book". RemoteWakeupConnected was |
529 | * saved if boot firmware (BIOS/SMM/...) told us it's connected | 540 | * saved if boot firmware (BIOS/SMM/...) told us it's connected, |
530 | * (for OHCI integrated on mainboard, it normally is) | 541 | * or if bus glue did the same (e.g. for PCI add-in cards with |
542 | * PCI PM support). | ||
531 | */ | 543 | */ |
532 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | ||
533 | ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n", | 544 | ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n", |
534 | hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), | 545 | hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), |
535 | ohci->hc_control); | 546 | ohci_readl (ohci, &ohci->regs->control)); |
536 | 547 | if ((ohci->hc_control & OHCI_CTRL_RWC) != 0 | |
537 | if (ohci->hc_control & OHCI_CTRL_RWC | 548 | && !device_may_wakeup(hcd->self.controller)) |
538 | && !(ohci->flags & OHCI_QUIRK_AMD756)) | 549 | device_init_wakeup(hcd->self.controller, 1); |
539 | ohci_to_hcd(ohci)->can_wakeup = 1; | ||
540 | 550 | ||
541 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { | 551 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { |
542 | case OHCI_USB_OPER: | 552 | case OHCI_USB_OPER: |
@@ -632,7 +642,7 @@ retry: | |||
632 | ohci->hc_control &= OHCI_CTRL_RWC; | 642 | ohci->hc_control &= OHCI_CTRL_RWC; |
633 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; | 643 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; |
634 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 644 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
635 | ohci_to_hcd(ohci)->state = HC_STATE_RUNNING; | 645 | hcd->state = HC_STATE_RUNNING; |
636 | 646 | ||
637 | /* wake on ConnectStatusChange, matching external hubs */ | 647 | /* wake on ConnectStatusChange, matching external hubs */ |
638 | ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); | 648 | ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); |
@@ -667,15 +677,10 @@ retry: | |||
667 | 677 | ||
668 | // POTPGT delay is bits 24-31, in 2 ms units. | 678 | // POTPGT delay is bits 24-31, in 2 ms units. |
669 | mdelay ((temp >> 23) & 0x1fe); | 679 | mdelay ((temp >> 23) & 0x1fe); |
670 | ohci_to_hcd(ohci)->state = HC_STATE_RUNNING; | 680 | hcd->state = HC_STATE_RUNNING; |
671 | 681 | ||
672 | ohci_dump (ohci, 1); | 682 | ohci_dump (ohci, 1); |
673 | 683 | ||
674 | if (ohci_to_hcd(ohci)->self.root_hub == NULL) { | ||
675 | register_reboot_notifier (&ohci->reboot_notifier); | ||
676 | create_debug_files (ohci); | ||
677 | } | ||
678 | |||
679 | return 0; | 684 | return 0; |
680 | } | 685 | } |
681 | 686 | ||
@@ -905,6 +910,10 @@ MODULE_LICENSE ("GPL"); | |||
905 | #include "ohci-ppc-soc.c" | 910 | #include "ohci-ppc-soc.c" |
906 | #endif | 911 | #endif |
907 | 912 | ||
913 | #ifdef CONFIG_ARCH_AT91RM9200 | ||
914 | #include "ohci-at91.c" | ||
915 | #endif | ||
916 | |||
908 | #if !(defined(CONFIG_PCI) \ | 917 | #if !(defined(CONFIG_PCI) \ |
909 | || defined(CONFIG_SA1111) \ | 918 | || defined(CONFIG_SA1111) \ |
910 | || defined(CONFIG_ARCH_S3C2410) \ | 919 | || defined(CONFIG_ARCH_S3C2410) \ |
@@ -913,6 +922,7 @@ MODULE_LICENSE ("GPL"); | |||
913 | || defined (CONFIG_PXA27x) \ | 922 | || defined (CONFIG_PXA27x) \ |
914 | || defined (CONFIG_SOC_AU1X00) \ | 923 | || defined (CONFIG_SOC_AU1X00) \ |
915 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ | 924 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ |
925 | || defined (CONFIG_ARCH_AT91RM9200) \ | ||
916 | ) | 926 | ) |
917 | #error "missing bus glue for ohci-hcd" | 927 | #error "missing bus glue for ohci-hcd" |
918 | #endif | 928 | #endif |