diff options
author | Florian Fainelli <florian@openwrt.org> | 2012-10-08 17:11:29 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-22 22:23:59 +0400 |
commit | cfa49b4b88fe14d2b5792f2ea7ba5b88c8cd1d15 (patch) | |
tree | 5a689a1365b7b0844421ec5a18a3a9af4d28c323 /drivers/usb/host/ohci-hcd.c | |
parent | d4ae47dc5670efecd2214110caf33dfc0ff7191f (diff) | |
download | linux-cfa49b4b88fe14d2b5792f2ea7ba5b88c8cd1d15.tar.xz |
USB: ohci: merge ohci_finish_controller_resume with ohci_resume
Merge ohci_finish_controller_resume with ohci_resume as suggested by Alan
Stern. Since ohci_finish_controller_resume no longer exists, update the
various OHCI drivers to call ohci_resume() instead. Some drivers used to set
themselves the bit HCD_FLAG_HW_ACCESSIBLE, which is now handled by
ohci_resume().
Acked-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 76663295e1c7..bac662636969 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1035,13 +1035,50 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) { + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int port; + bool need_reinit = false; + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* Make sure resume from hibernation re-enumerates everything */ if (hibernated) - ohci_usb_reset(hcd_to_ohci(hcd)); + ohci_usb_reset(ohci); + + /* See if the controller is already running or has been reset */ + ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); + if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { + need_reinit = true; + } else { + switch (ohci->hc_control & OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + case OHCI_USB_RESET: + need_reinit = true; + } + } + + /* If needed, reinitialize and suspend the root hub */ + if (need_reinit) { + spin_lock_irq(&ohci->lock); + ohci_rh_resume(ohci); + ohci_rh_suspend(ohci, 0); + spin_unlock_irq(&ohci->lock); + } + + /* Normally just turn on port power and enable interrupts */ + else { + ohci_dbg(ohci, "powerup ports\n"); + for (port = 0; port < ohci->num_ports; port++) + ohci_writel(ohci, RH_PS_PPS, + &ohci->regs->roothub.portstatus[port]); + + ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); + ohci_readl(ohci, &ohci->regs->intrenable); + msleep(20); + } + + usb_hcd_resume_root_hub(hcd); - ohci_finish_controller_resume(hcd); return 0; } |