diff options
-rw-r--r-- | drivers/usb/host/ohci-at91.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index e2b8b7bc08ec..7cce85a1f7dc 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -42,6 +42,7 @@ struct ohci_at91_priv { | |||
42 | struct clk *uclk; | 42 | struct clk *uclk; |
43 | struct clk *hclk; | 43 | struct clk *hclk; |
44 | bool clocked; | 44 | bool clocked; |
45 | bool wakeup; /* Saved wake-up state for resume */ | ||
45 | }; | 46 | }; |
46 | /* interface and function clocks; sometimes also an AHB clock */ | 47 | /* interface and function clocks; sometimes also an AHB clock */ |
47 | 48 | ||
@@ -61,6 +62,8 @@ extern int usb_disabled(void); | |||
61 | 62 | ||
62 | static void at91_start_clock(struct ohci_at91_priv *ohci_at91) | 63 | static void at91_start_clock(struct ohci_at91_priv *ohci_at91) |
63 | { | 64 | { |
65 | if (ohci_at91->clocked) | ||
66 | return; | ||
64 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { | 67 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { |
65 | clk_set_rate(ohci_at91->uclk, 48000000); | 68 | clk_set_rate(ohci_at91->uclk, 48000000); |
66 | clk_prepare_enable(ohci_at91->uclk); | 69 | clk_prepare_enable(ohci_at91->uclk); |
@@ -73,6 +76,8 @@ static void at91_start_clock(struct ohci_at91_priv *ohci_at91) | |||
73 | 76 | ||
74 | static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) | 77 | static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) |
75 | { | 78 | { |
79 | if (!ohci_at91->clocked) | ||
80 | return; | ||
76 | clk_disable_unprepare(ohci_at91->fclk); | 81 | clk_disable_unprepare(ohci_at91->fclk); |
77 | clk_disable_unprepare(ohci_at91->iclk); | 82 | clk_disable_unprepare(ohci_at91->iclk); |
78 | clk_disable_unprepare(ohci_at91->hclk); | 83 | clk_disable_unprepare(ohci_at91->hclk); |
@@ -616,15 +621,22 @@ ohci_hcd_at91_drv_suspend(struct device *dev) | |||
616 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 621 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
617 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | 622 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
618 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); | 623 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); |
619 | bool do_wakeup = device_may_wakeup(dev); | ||
620 | int ret; | 624 | int ret; |
621 | 625 | ||
622 | if (do_wakeup) | 626 | /* |
627 | * Disable wakeup if we are going to sleep with slow clock mode | ||
628 | * enabled. | ||
629 | */ | ||
630 | ohci_at91->wakeup = device_may_wakeup(dev) | ||
631 | && !at91_suspend_entering_slow_clock(); | ||
632 | |||
633 | if (ohci_at91->wakeup) | ||
623 | enable_irq_wake(hcd->irq); | 634 | enable_irq_wake(hcd->irq); |
624 | 635 | ||
625 | ret = ohci_suspend(hcd, do_wakeup); | 636 | ret = ohci_suspend(hcd, ohci_at91->wakeup); |
626 | if (ret) { | 637 | if (ret) { |
627 | disable_irq_wake(hcd->irq); | 638 | if (ohci_at91->wakeup) |
639 | disable_irq_wake(hcd->irq); | ||
628 | return ret; | 640 | return ret; |
629 | } | 641 | } |
630 | /* | 642 | /* |
@@ -634,7 +646,7 @@ ohci_hcd_at91_drv_suspend(struct device *dev) | |||
634 | * | 646 | * |
635 | * REVISIT: some boards will be able to turn VBUS off... | 647 | * REVISIT: some boards will be able to turn VBUS off... |
636 | */ | 648 | */ |
637 | if (at91_suspend_entering_slow_clock()) { | 649 | if (!ohci_at91->wakeup) { |
638 | ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); | 650 | ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); |
639 | ohci->hc_control &= OHCI_CTRL_RWC; | 651 | ohci->hc_control &= OHCI_CTRL_RWC; |
640 | ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); | 652 | ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); |
@@ -653,11 +665,10 @@ static int ohci_hcd_at91_drv_resume(struct device *dev) | |||
653 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 665 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
654 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); | 666 | struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); |
655 | 667 | ||
656 | if (device_may_wakeup(dev)) | 668 | if (ohci_at91->wakeup) |
657 | disable_irq_wake(hcd->irq); | 669 | disable_irq_wake(hcd->irq); |
658 | 670 | ||
659 | if (!ohci_at91->clocked) | 671 | at91_start_clock(ohci_at91); |
660 | at91_start_clock(ohci_at91); | ||
661 | 672 | ||
662 | ohci_resume(hcd, false); | 673 | ohci_resume(hcd, false); |
663 | return 0; | 674 | return 0; |