aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ohci-at91.c27
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
62static void at91_start_clock(struct ohci_at91_priv *ohci_at91) 63static 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
74static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) 77static 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;