diff options
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2990be269000..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) 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; } |