diff options
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
| -rw-r--r-- | drivers/usb/host/ohci-hcd.c | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 94d8cf4b36c1..1027aa04583d 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
| @@ -88,7 +88,7 @@ | |||
| 88 | #include <linux/timer.h> | 88 | #include <linux/timer.h> |
| 89 | #include <linux/list.h> | 89 | #include <linux/list.h> |
| 90 | #include <linux/usb.h> | 90 | #include <linux/usb.h> |
| 91 | #include <linux/usb_otg.h> | 91 | #include <linux/usb/otg.h> |
| 92 | #include <linux/dma-mapping.h> | 92 | #include <linux/dma-mapping.h> |
| 93 | #include <linux/dmapool.h> | 93 | #include <linux/dmapool.h> |
| 94 | #include <linux/reboot.h> | 94 | #include <linux/reboot.h> |
| @@ -101,7 +101,7 @@ | |||
| 101 | 101 | ||
| 102 | #include "../core/hcd.h" | 102 | #include "../core/hcd.h" |
| 103 | 103 | ||
| 104 | #define DRIVER_VERSION "2005 April 22" | 104 | #define DRIVER_VERSION "2006 August 04" |
| 105 | #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" | 105 | #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" |
| 106 | #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" | 106 | #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" |
| 107 | 107 | ||
| @@ -110,9 +110,10 @@ | |||
| 110 | #undef OHCI_VERBOSE_DEBUG /* not always helpful */ | 110 | #undef OHCI_VERBOSE_DEBUG /* not always helpful */ |
| 111 | 111 | ||
| 112 | /* For initializing controller (mask in an HCFS mode too) */ | 112 | /* For initializing controller (mask in an HCFS mode too) */ |
| 113 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR | 113 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR |
| 114 | #define OHCI_INTR_INIT \ | 114 | #define OHCI_INTR_INIT \ |
| 115 | (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_WDH) | 115 | (OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE \ |
| 116 | | OHCI_INTR_RD | OHCI_INTR_WDH) | ||
| 116 | 117 | ||
| 117 | #ifdef __hppa__ | 118 | #ifdef __hppa__ |
| 118 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | 119 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ |
| @@ -128,12 +129,13 @@ | |||
| 128 | 129 | ||
| 129 | static const char hcd_name [] = "ohci_hcd"; | 130 | static const char hcd_name [] = "ohci_hcd"; |
| 130 | 131 | ||
| 132 | #define STATECHANGE_DELAY msecs_to_jiffies(300) | ||
| 133 | |||
| 131 | #include "ohci.h" | 134 | #include "ohci.h" |
| 132 | 135 | ||
| 133 | static void ohci_dump (struct ohci_hcd *ohci, int verbose); | 136 | static void ohci_dump (struct ohci_hcd *ohci, int verbose); |
| 134 | static int ohci_init (struct ohci_hcd *ohci); | 137 | static int ohci_init (struct ohci_hcd *ohci); |
| 135 | static void ohci_stop (struct usb_hcd *hcd); | 138 | static void ohci_stop (struct usb_hcd *hcd); |
| 136 | static int ohci_reboot (struct notifier_block *, unsigned long , void *); | ||
| 137 | 139 | ||
| 138 | #include "ohci-hub.c" | 140 | #include "ohci-hub.c" |
| 139 | #include "ohci-dbg.c" | 141 | #include "ohci-dbg.c" |
| @@ -416,21 +418,20 @@ static void ohci_usb_reset (struct ohci_hcd *ohci) | |||
| 416 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 418 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
| 417 | } | 419 | } |
| 418 | 420 | ||
| 419 | /* reboot notifier forcibly disables IRQs and DMA, helping kexec and | 421 | /* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and |
| 420 | * other cases where the next software may expect clean state from the | 422 | * other cases where the next software may expect clean state from the |
| 421 | * "firmware". this is bus-neutral, unlike shutdown() methods. | 423 | * "firmware". this is bus-neutral, unlike shutdown() methods. |
| 422 | */ | 424 | */ |
| 423 | static int | 425 | static void |
| 424 | ohci_reboot (struct notifier_block *block, unsigned long code, void *null) | 426 | ohci_shutdown (struct usb_hcd *hcd) |
| 425 | { | 427 | { |
| 426 | struct ohci_hcd *ohci; | 428 | struct ohci_hcd *ohci; |
| 427 | 429 | ||
| 428 | ohci = container_of (block, struct ohci_hcd, reboot_notifier); | 430 | ohci = hcd_to_ohci (hcd); |
| 429 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 431 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
| 430 | ohci_usb_reset (ohci); | 432 | ohci_usb_reset (ohci); |
| 431 | /* flush the writes */ | 433 | /* flush the writes */ |
| 432 | (void) ohci_readl (ohci, &ohci->regs->control); | 434 | (void) ohci_readl (ohci, &ohci->regs->control); |
| 433 | return 0; | ||
| 434 | } | 435 | } |
| 435 | 436 | ||
| 436 | /*-------------------------------------------------------------------------* | 437 | /*-------------------------------------------------------------------------* |
| @@ -446,7 +447,6 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
| 446 | 447 | ||
| 447 | disable (ohci); | 448 | disable (ohci); |
| 448 | ohci->regs = hcd->regs; | 449 | ohci->regs = hcd->regs; |
| 449 | ohci->next_statechange = jiffies; | ||
| 450 | 450 | ||
| 451 | /* REVISIT this BIOS handshake is now moved into PCI "quirks", and | 451 | /* REVISIT this BIOS handshake is now moved into PCI "quirks", and |
| 452 | * was never needed for most non-PCI systems ... remove the code? | 452 | * was never needed for most non-PCI systems ... remove the code? |
| @@ -502,7 +502,6 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
| 502 | if ((ret = ohci_mem_init (ohci)) < 0) | 502 | if ((ret = ohci_mem_init (ohci)) < 0) |
| 503 | ohci_stop (hcd); | 503 | ohci_stop (hcd); |
| 504 | else { | 504 | else { |
| 505 | register_reboot_notifier (&ohci->reboot_notifier); | ||
| 506 | create_debug_files (ohci); | 505 | create_debug_files (ohci); |
| 507 | } | 506 | } |
| 508 | 507 | ||
| @@ -637,10 +636,14 @@ retry: | |||
| 637 | return -EOVERFLOW; | 636 | return -EOVERFLOW; |
| 638 | } | 637 | } |
| 639 | 638 | ||
| 640 | /* start controller operations */ | 639 | /* use rhsc irqs after khubd is fully initialized */ |
| 640 | hcd->poll_rh = 1; | ||
| 641 | hcd->uses_new_polling = 1; | ||
| 642 | |||
| 643 | /* start controller operations */ | ||
| 641 | ohci->hc_control &= OHCI_CTRL_RWC; | 644 | ohci->hc_control &= OHCI_CTRL_RWC; |
| 642 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; | 645 | ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; |
| 643 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 646 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
| 644 | hcd->state = HC_STATE_RUNNING; | 647 | hcd->state = HC_STATE_RUNNING; |
| 645 | 648 | ||
| 646 | /* wake on ConnectStatusChange, matching external hubs */ | 649 | /* wake on ConnectStatusChange, matching external hubs */ |
| @@ -648,7 +651,7 @@ retry: | |||
| 648 | 651 | ||
| 649 | /* Choose the interrupts we care about now, others later on demand */ | 652 | /* Choose the interrupts we care about now, others later on demand */ |
| 650 | mask = OHCI_INTR_INIT; | 653 | mask = OHCI_INTR_INIT; |
| 651 | ohci_writel (ohci, mask, &ohci->regs->intrstatus); | 654 | ohci_writel (ohci, ~0, &ohci->regs->intrstatus); |
| 652 | ohci_writel (ohci, mask, &ohci->regs->intrenable); | 655 | ohci_writel (ohci, mask, &ohci->regs->intrenable); |
| 653 | 656 | ||
| 654 | /* handle root hub init quirks ... */ | 657 | /* handle root hub init quirks ... */ |
| @@ -672,6 +675,7 @@ retry: | |||
| 672 | // flush those writes | 675 | // flush those writes |
| 673 | (void) ohci_readl (ohci, &ohci->regs->control); | 676 | (void) ohci_readl (ohci, &ohci->regs->control); |
| 674 | 677 | ||
| 678 | ohci->next_statechange = jiffies + STATECHANGE_DELAY; | ||
| 675 | spin_unlock_irq (&ohci->lock); | 679 | spin_unlock_irq (&ohci->lock); |
| 676 | 680 | ||
| 677 | // POTPGT delay is bits 24-31, in 2 ms units. | 681 | // POTPGT delay is bits 24-31, in 2 ms units. |
| @@ -709,7 +713,23 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) | |||
| 709 | /* interrupt for some other device? */ | 713 | /* interrupt for some other device? */ |
| 710 | } else if ((ints &= ohci_readl (ohci, ®s->intrenable)) == 0) { | 714 | } else if ((ints &= ohci_readl (ohci, ®s->intrenable)) == 0) { |
| 711 | return IRQ_NOTMINE; | 715 | return IRQ_NOTMINE; |
| 712 | } | 716 | } |
| 717 | |||
| 718 | /* NOTE: vendors didn't always make the same implementation | ||
| 719 | * choices for RHSC. Sometimes it triggers on an edge (like | ||
| 720 | * setting and maybe clearing a port status change bit); and | ||
| 721 | * it's level-triggered on other silicon, active until khubd | ||
| 722 | * clears all active port status change bits. Poll by timer | ||
| 723 | * til it's fully debounced and the difference won't matter. | ||
| 724 | */ | ||
| 725 | if (ints & OHCI_INTR_RHSC) { | ||
| 726 | ohci_vdbg (ohci, "rhsc\n"); | ||
| 727 | ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrdisable); | ||
| 728 | hcd->poll_rh = 1; | ||
| 729 | ohci->next_statechange = jiffies + STATECHANGE_DELAY; | ||
| 730 | ohci_writel (ohci, OHCI_INTR_RHSC, ®s->intrstatus); | ||
| 731 | usb_hcd_poll_rh_status(hcd); | ||
| 732 | } | ||
| 713 | 733 | ||
| 714 | if (ints & OHCI_INTR_UE) { | 734 | if (ints & OHCI_INTR_UE) { |
| 715 | disable (ohci); | 735 | disable (ohci); |
| @@ -775,9 +795,10 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
| 775 | 795 | ||
| 776 | ohci_usb_reset (ohci); | 796 | ohci_usb_reset (ohci); |
| 777 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 797 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
| 778 | 798 | free_irq(hcd->irq, hcd); | |
| 799 | hcd->irq = -1; | ||
| 800 | |||
| 779 | remove_debug_files (ohci); | 801 | remove_debug_files (ohci); |
| 780 | unregister_reboot_notifier (&ohci->reboot_notifier); | ||
| 781 | ohci_mem_cleanup (ohci); | 802 | ohci_mem_cleanup (ohci); |
| 782 | if (ohci->hcca) { | 803 | if (ohci->hcca) { |
| 783 | dma_free_coherent (hcd->self.controller, | 804 | dma_free_coherent (hcd->self.controller, |
| @@ -917,6 +938,10 @@ MODULE_LICENSE ("GPL"); | |||
| 917 | #include "ohci-at91.c" | 938 | #include "ohci-at91.c" |
| 918 | #endif | 939 | #endif |
| 919 | 940 | ||
| 941 | #ifdef CONFIG_ARCH_PNX4008 | ||
| 942 | #include "ohci-pnx4008.c" | ||
| 943 | #endif | ||
| 944 | |||
| 920 | #if !(defined(CONFIG_PCI) \ | 945 | #if !(defined(CONFIG_PCI) \ |
| 921 | || defined(CONFIG_SA1111) \ | 946 | || defined(CONFIG_SA1111) \ |
| 922 | || defined(CONFIG_ARCH_S3C2410) \ | 947 | || defined(CONFIG_ARCH_S3C2410) \ |
| @@ -928,6 +953,7 @@ MODULE_LICENSE ("GPL"); | |||
| 928 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ | 953 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ |
| 929 | || defined (CONFIG_ARCH_AT91RM9200) \ | 954 | || defined (CONFIG_ARCH_AT91RM9200) \ |
| 930 | || defined (CONFIG_ARCH_AT91SAM9261) \ | 955 | || defined (CONFIG_ARCH_AT91SAM9261) \ |
| 956 | || defined (CONFIG_ARCH_PNX4008) \ | ||
| 931 | ) | 957 | ) |
| 932 | #error "missing bus glue for ohci-hcd" | 958 | #error "missing bus glue for ohci-hcd" |
| 933 | #endif | 959 | #endif |
