diff options
-rw-r--r-- | drivers/usb/host/ohci-at91.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-ep93xx.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 43 | ||||
-rw-r--r-- | drivers/usb/host/ohci-omap.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 43 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pxa27x.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/ohci-sm501.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/ohci-ssb.c | 1 |
8 files changed, 54 insertions, 49 deletions
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index d72dc07dda01..e534f9de0f05 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -348,6 +348,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) | |||
348 | if (!clocked) | 348 | if (!clocked) |
349 | at91_start_clock(); | 349 | at91_start_clock(); |
350 | 350 | ||
351 | ohci_finish_controller_resume(hcd); | ||
351 | return 0; | 352 | return 0; |
352 | } | 353 | } |
353 | #else | 354 | #else |
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 40c683f8987d..5adaf36e47d0 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c | |||
@@ -192,8 +192,8 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) | |||
192 | ohci->next_statechange = jiffies; | 192 | ohci->next_statechange = jiffies; |
193 | 193 | ||
194 | ep93xx_start_hc(&pdev->dev); | 194 | ep93xx_start_hc(&pdev->dev); |
195 | usb_hcd_resume_root_hub(hcd); | ||
196 | 195 | ||
196 | ohci_finish_controller_resume(hcd); | ||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | #endif | 199 | #endif |
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) |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 2aafa7b6c81f..3a7c24c03671 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -510,14 +510,15 @@ static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) | |||
510 | 510 | ||
511 | static int ohci_omap_resume(struct platform_device *dev) | 511 | static int ohci_omap_resume(struct platform_device *dev) |
512 | { | 512 | { |
513 | struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); | 513 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
514 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
514 | 515 | ||
515 | if (time_before(jiffies, ohci->next_statechange)) | 516 | if (time_before(jiffies, ohci->next_statechange)) |
516 | msleep(5); | 517 | msleep(5); |
517 | ohci->next_statechange = jiffies; | 518 | ohci->next_statechange = jiffies; |
518 | 519 | ||
519 | omap_ohci_clock_power(1); | 520 | omap_ohci_clock_power(1); |
520 | usb_hcd_resume_root_hub(platform_get_drvdata(dev)); | 521 | ohci_finish_controller_resume(hcd); |
521 | return 0; | 522 | return 0; |
522 | } | 523 | } |
523 | 524 | ||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 40b62a35fd3c..4696cc912e16 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -238,42 +238,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd) | |||
238 | return ret; | 238 | return ret; |
239 | } | 239 | } |
240 | 240 | ||
241 | #if defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \ | ||
242 | defined(CONFIG_USB_EHCI_HCD_MODULE)) | ||
243 | |||
244 | /* Following a power loss, we must prepare to regain control of the ports | ||
245 | * we used to own. This means turning on the port power before ehci-hcd | ||
246 | * tries to switch ownership. | ||
247 | * | ||
248 | * This isn't a 100% perfect solution. On most systems the OHCI controllers | ||
249 | * lie at lower PCI addresses than the EHCI controller, so they will be | ||
250 | * discovered (and hence resumed) first. But there is no guarantee things | ||
251 | * will always work this way. If the EHCI controller is resumed first and | ||
252 | * the OHCI ports are unpowered, then the handover will fail. | ||
253 | */ | ||
254 | static void prepare_for_handover(struct usb_hcd *hcd) | ||
255 | { | ||
256 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
257 | int port; | ||
258 | |||
259 | /* Here we "know" root ports should always stay powered */ | ||
260 | ohci_dbg(ohci, "powerup ports\n"); | ||
261 | for (port = 0; port < ohci->num_ports; port++) | ||
262 | ohci_writel(ohci, RH_PS_PPS, | ||
263 | &ohci->regs->roothub.portstatus[port]); | ||
264 | |||
265 | /* Flush those writes */ | ||
266 | ohci_readl(ohci, &ohci->regs->control); | ||
267 | msleep(20); | ||
268 | } | ||
269 | |||
270 | #else | ||
271 | |||
272 | static inline void prepare_for_handover(struct usb_hcd *hcd) | ||
273 | { } | ||
274 | |||
275 | #endif /* CONFIG_USB_PERSIST etc. */ | ||
276 | |||
277 | #ifdef CONFIG_PM | 241 | #ifdef CONFIG_PM |
278 | 242 | ||
279 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | 243 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) |
@@ -312,13 +276,8 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | |||
312 | 276 | ||
313 | static int ohci_pci_resume (struct usb_hcd *hcd) | 277 | static int ohci_pci_resume (struct usb_hcd *hcd) |
314 | { | 278 | { |
315 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
316 | |||
317 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 279 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
318 | 280 | ohci_finish_controller_resume(hcd); | |
319 | /* FIXME: we should try to detect loss of VBUS power here */ | ||
320 | prepare_for_handover(hcd); | ||
321 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); | ||
322 | return 0; | 281 | return 0; |
323 | } | 282 | } |
324 | 283 | ||
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 5d470263eed8..d4ee27d92be8 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -356,8 +356,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) | |||
356 | if ((status = pxa27x_start_hc(&pdev->dev)) < 0) | 356 | if ((status = pxa27x_start_hc(&pdev->dev)) < 0) |
357 | return status; | 357 | return status; |
358 | 358 | ||
359 | usb_hcd_resume_root_hub(hcd); | 359 | ohci_finish_controller_resume(hcd); |
360 | |||
361 | return 0; | 360 | return 0; |
362 | } | 361 | } |
363 | #endif | 362 | #endif |
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 54b6ac2e3e4a..4a11e1816017 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c | |||
@@ -231,14 +231,15 @@ static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg) | |||
231 | static int ohci_sm501_resume(struct platform_device *pdev) | 231 | static int ohci_sm501_resume(struct platform_device *pdev) |
232 | { | 232 | { |
233 | struct device *dev = &pdev->dev; | 233 | struct device *dev = &pdev->dev; |
234 | struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(pdev)); | 234 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
235 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
235 | 236 | ||
236 | if (time_before(jiffies, ohci->next_statechange)) | 237 | if (time_before(jiffies, ohci->next_statechange)) |
237 | msleep(5); | 238 | msleep(5); |
238 | ohci->next_statechange = jiffies; | 239 | ohci->next_statechange = jiffies; |
239 | 240 | ||
240 | sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); | 241 | sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); |
241 | usb_hcd_resume_root_hub(platform_get_drvdata(pdev)); | 242 | ohci_finish_controller_resume(hcd); |
242 | return 0; | 243 | return 0; |
243 | } | 244 | } |
244 | #else | 245 | #else |
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c index 7879f2fdad84..7275186db315 100644 --- a/drivers/usb/host/ohci-ssb.c +++ b/drivers/usb/host/ohci-ssb.c | |||
@@ -189,6 +189,7 @@ static int ssb_ohci_resume(struct ssb_device *dev) | |||
189 | 189 | ||
190 | ssb_device_enable(dev, ohcidev->enable_flags); | 190 | ssb_device_enable(dev, ohcidev->enable_flags); |
191 | 191 | ||
192 | ohci_finish_controller_resume(hcd); | ||
192 | return 0; | 193 | return 0; |
193 | } | 194 | } |
194 | 195 | ||