diff options
-rw-r--r-- | drivers/usb/host/ohci-omap.c | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index b62d69937694..5cde76faab93 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -456,34 +456,22 @@ static int ohci_hcd_omap_drv_remove(struct device *dev) | |||
456 | 456 | ||
457 | #ifdef CONFIG_PM | 457 | #ifdef CONFIG_PM |
458 | 458 | ||
459 | /* states match PCI usage, always suspending the root hub except that | 459 | static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level) |
460 | * 4 ~= D3cold (ACPI D3) with clock off (resume sees reset). | ||
461 | * | ||
462 | * FIXME: above comment is not right, and code is wrong, too :-(. | ||
463 | */ | ||
464 | |||
465 | static int ohci_omap_suspend(struct device *dev, pm_message_t state, u32 level) | ||
466 | { | 460 | { |
467 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 461 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); |
468 | int status = -EINVAL; | 462 | int status = -EINVAL; |
469 | 463 | ||
470 | if (level != SUSPEND_POWER_DOWN) | 464 | if (level != SUSPEND_POWER_DOWN) |
471 | return 0; | 465 | return 0; |
472 | if (state <= dev->power.power_state) | ||
473 | return 0; | ||
474 | 466 | ||
475 | dev_dbg(dev, "suspend to %d\n", state); | ||
476 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 467 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
477 | status = ohci_hub_suspend(ohci_to_hcd(ohci)); | 468 | status = ohci_hub_suspend(ohci_to_hcd(ohci)); |
478 | if (status == 0) { | 469 | if (status == 0) { |
479 | if (state >= 4) { | 470 | omap_ohci_clock_power(0); |
480 | omap_ohci_clock_power(0); | 471 | ohci_to_hcd(ohci)->self.root_hub->state = |
481 | ohci_to_hcd(ohci)->self.root_hub->state = | 472 | USB_STATE_SUSPENDED; |
482 | USB_STATE_SUSPENDED; | ||
483 | state = 4; | ||
484 | } | ||
485 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | 473 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; |
486 | dev->power.power_state = state; | 474 | dev->power.power_state = PMSG_SUSPEND; |
487 | } | 475 | } |
488 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 476 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
489 | return status; | 477 | return status; |
@@ -497,29 +485,20 @@ static int ohci_omap_resume(struct device *dev, u32 level) | |||
497 | if (level != RESUME_POWER_ON) | 485 | if (level != RESUME_POWER_ON) |
498 | return 0; | 486 | return 0; |
499 | 487 | ||
500 | switch (dev->power.power_state) { | 488 | if (time_before(jiffies, ohci->next_statechange)) |
501 | case 0: | 489 | msleep(5); |
502 | break; | 490 | ohci->next_statechange = jiffies; |
503 | case 4: | 491 | omap_ohci_clock_power(1); |
504 | if (time_before(jiffies, ohci->next_statechange)) | ||
505 | msleep(5); | ||
506 | ohci->next_statechange = jiffies; | ||
507 | omap_ohci_clock_power(1); | ||
508 | /* FALLTHROUGH */ | ||
509 | default: | ||
510 | dev_dbg(dev, "resume from %d\n", dev->power.power_state); | ||
511 | #ifdef CONFIG_USB_SUSPEND | 492 | #ifdef CONFIG_USB_SUSPEND |
512 | /* get extra cleanup even if remote wakeup isn't in use */ | 493 | /* get extra cleanup even if remote wakeup isn't in use */ |
513 | status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); | 494 | status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); |
514 | #else | 495 | #else |
515 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 496 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
516 | status = ohci_hub_resume(ohci_to_hcd(ohci)); | 497 | status = ohci_hub_resume(ohci_to_hcd(ohci)); |
517 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 498 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
518 | #endif | 499 | #endif |
519 | if (status == 0) | 500 | if (status == 0) |
520 | dev->power.power_state = 0; | 501 | dev->power.power_state = PMSG_ON; |
521 | break; | ||
522 | } | ||
523 | return status; | 502 | return status; |
524 | } | 503 | } |
525 | 504 | ||