]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/host/ohci-hcd.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-omap-h63xx.git] / drivers / usb / host / ohci-hcd.c
index 2990be2690008d6f2006cbac72be22e5d510127e..73f5a379d9b332a37e73b100862ad3c817e0df9e 100644 (file)
@@ -443,11 +443,16 @@ ohci_reboot (struct notifier_block *block, unsigned long code, void *null)
 static int ohci_init (struct ohci_hcd *ohci)
 {
        int ret;
+       struct usb_hcd *hcd = ohci_to_hcd(ohci);
 
        disable (ohci);
-       ohci->regs = ohci_to_hcd(ohci)->regs;
+       ohci->regs = hcd->regs;
        ohci->next_statechange = jiffies;
 
+       /* REVISIT this BIOS handshake is now moved into PCI "quirks", and
+        * was never needed for most non-PCI systems ... remove the code?
+        */
+
 #ifndef IR_DISABLE
        /* SMM owns the HC?  not for long! */
        if (!no_handshake && ohci_readl (ohci,
@@ -478,8 +483,10 @@ static int ohci_init (struct ohci_hcd *ohci)
 
        /* Disable HC interrupts */
        ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
-       // flush the writes
-       (void) ohci_readl (ohci, &ohci->regs->control);
+
+       /* flush the writes, and save key bits like RWC */
+       if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC)
+               ohci->hc_control |= OHCI_CTRL_RWC;
 
        /* Read the number of ports unless overridden */
        if (ohci->num_ports == 0)
@@ -488,16 +495,19 @@ static int ohci_init (struct ohci_hcd *ohci)
        if (ohci->hcca)
                return 0;
 
-       ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller,
+       ohci->hcca = dma_alloc_coherent (hcd->self.controller,
                        sizeof *ohci->hcca, &ohci->hcca_dma, 0);
        if (!ohci->hcca)
                return -ENOMEM;
 
        if ((ret = ohci_mem_init (ohci)) < 0)
-               ohci_stop (ohci_to_hcd(ohci));
+               ohci_stop (hcd);
+       else {
+               register_reboot_notifier (&ohci->reboot_notifier);
+               create_debug_files (ohci);
+       }
 
        return ret;
-
 }
 
 /*-------------------------------------------------------------------------*/
@@ -510,6 +520,7 @@ static int ohci_run (struct ohci_hcd *ohci)
 {
        u32                     mask, temp;
        int                     first = ohci->fminterval == 0;
+       struct usb_hcd          *hcd = ohci_to_hcd(ohci);
 
        disable (ohci);
 
@@ -525,18 +536,17 @@ static int ohci_run (struct ohci_hcd *ohci)
                /* also: power/overcurrent flags in roothub.a */
        }
 
-       /* Reset USB nearly "by the book".  RemoteWakeupConnected
-        * saved if boot firmware (BIOS/SMM/...) told us it's connected
-        * (for OHCI integrated on mainboard, it normally is)
+       /* Reset USB nearly "by the book".  RemoteWakeupConnected was
+        * saved if boot firmware (BIOS/SMM/...) told us it's connected,
+        * or if bus glue did the same (e.g. for PCI add-in cards with
+        * PCI PM support).
         */
-       ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
        ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n",
                        hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
-                       ohci->hc_control);
-
-       if (ohci->hc_control & OHCI_CTRL_RWC
-                       && !(ohci->flags & OHCI_QUIRK_AMD756))
-               ohci_to_hcd(ohci)->can_wakeup = 1;
+                       ohci_readl (ohci, &ohci->regs->control));
+       if ((ohci->hc_control & OHCI_CTRL_RWC) != 0
+                       && !device_may_wakeup(hcd->self.controller))
+               device_init_wakeup(hcd->self.controller, 1);
 
        switch (ohci->hc_control & OHCI_CTRL_HCFS) {
        case OHCI_USB_OPER:
@@ -632,7 +642,7 @@ retry:
        ohci->hc_control &= OHCI_CTRL_RWC;
        ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
        ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
-       ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
+       hcd->state = HC_STATE_RUNNING;
 
        /* wake on ConnectStatusChange, matching external hubs */
        ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
@@ -667,15 +677,10 @@ retry:
 
        // POTPGT delay is bits 24-31, in 2 ms units.
        mdelay ((temp >> 23) & 0x1fe);
-       ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
+       hcd->state = HC_STATE_RUNNING;
 
        ohci_dump (ohci, 1);
 
-       if (ohci_to_hcd(ohci)->self.root_hub == NULL) {
-               register_reboot_notifier (&ohci->reboot_notifier);
-               create_debug_files (ohci);
-       }
-
        return 0;
 }
 
@@ -858,7 +863,7 @@ static int ohci_restart (struct ohci_hcd *ohci)
                i = ohci->num_ports;
                while (i--)
                        ohci_writel (ohci, RH_PS_PSS,
-                               &ohci->regs->roothub.portstatus [temp]);
+                               &ohci->regs->roothub.portstatus [i]);
                ohci_dbg (ohci, "restart complete\n");
        }
        return 0;