diff options
Diffstat (limited to 'drivers/usb/host/ohci-hub.c')
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index c638e6b33c43..28d6d775eb5f 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -326,6 +326,49 @@ static int ohci_bus_resume (struct usb_hcd *hcd) | |||
326 | return rc; | 326 | return rc; |
327 | } | 327 | } |
328 | 328 | ||
329 | /* Carry out the final steps of resuming the controller device */ | ||
330 | static void ohci_finish_controller_resume(struct usb_hcd *hcd) | ||
331 | { | ||
332 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
333 | int port; | ||
334 | bool need_reinit = false; | ||
335 | |||
336 | /* See if the controller is already running or has been reset */ | ||
337 | ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); | ||
338 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { | ||
339 | need_reinit = true; | ||
340 | } else { | ||
341 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { | ||
342 | case OHCI_USB_OPER: | ||
343 | case OHCI_USB_RESET: | ||
344 | need_reinit = true; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | /* If needed, reinitialize and suspend the root hub */ | ||
349 | if (need_reinit) { | ||
350 | spin_lock_irq(&ohci->lock); | ||
351 | hcd->state = HC_STATE_RESUMING; | ||
352 | ohci_rh_resume(ohci); | ||
353 | hcd->state = HC_STATE_QUIESCING; | ||
354 | ohci_rh_suspend(ohci, 0); | ||
355 | hcd->state = HC_STATE_SUSPENDED; | ||
356 | spin_unlock_irq(&ohci->lock); | ||
357 | } | ||
358 | |||
359 | /* Normally just turn on port power and enable interrupts */ | ||
360 | else { | ||
361 | ohci_dbg(ohci, "powerup ports\n"); | ||
362 | for (port = 0; port < ohci->num_ports; port++) | ||
363 | ohci_writel(ohci, RH_PS_PPS, | ||
364 | &ohci->regs->roothub.portstatus[port]); | ||
365 | |||
366 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); | ||
367 | ohci_readl(ohci, &ohci->regs->intrenable); | ||
368 | msleep(20); | ||
369 | } | ||
370 | } | ||
371 | |||
329 | /* Carry out polling-, autostop-, and autoresume-related state changes */ | 372 | /* Carry out polling-, autostop-, and autoresume-related state changes */ |
330 | static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, | 373 | static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, |
331 | int any_connected) | 374 | int any_connected) |