summaryrefslogtreecommitdiff
path: root/drivers/usb/host/ehci-s5p.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2012-06-28 19:19:02 +0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-09 19:54:18 +0400
commitc5cf9212a368d88fe1e25797699b167f6daa64a5 (patch)
treecaaa246923f277de3a72e4d642f9fa914ba98a31 /drivers/usb/host/ehci-s5p.c
parent336c5c310e8f0d5baba7973765339eaf5d989fe1 (diff)
downloadlinux-c5cf9212a368d88fe1e25797699b167f6daa64a5.tar.xz
EHCI: centralize controller suspend/resume
This patch (as1563) removes a lot of duplicated code by moving the EHCI controller suspend/resume routines into the core driver, where the various platform drivers can invoke them as needed. Not only does this simplify these platform drivers, this also makes it easier for other platform drivers to add suspend/resume support in the future. Note: The patch does not touch the ehci-fsl.c file, because its approach to suspend and resume is so different from all the others. It will have to be handled specially by its maintainer. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-s5p.c')
-rw-r--r--drivers/usb/host/ehci-s5p.c61
1 files changed, 4 insertions, 57 deletions
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 1e483f052ff7..c7e0936d4a7c 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -200,27 +200,12 @@ static int s5p_ehci_suspend(struct device *dev)
{
struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
struct usb_hcd *hcd = s5p_ehci->hcd;
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ bool do_wakeup = device_may_wakeup(dev);
struct platform_device *pdev = to_platform_device(dev);
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
- unsigned long flags;
- int rc = 0;
+ int rc;
- if (time_before(jiffies, ehci->next_statechange))
- msleep(20);
-
- /*
- * Root hub was already suspended. Disable irq emission and
- * mark HW unaccessible. The PM and USB cores make sure that
- * the root hub is either suspended or stopped.
- */
- ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
- spin_lock_irqsave(&ehci->lock, flags);
- ehci_writel(ehci, 0, &ehci->regs->intr_enable);
- (void)ehci_readl(ehci, &ehci->regs->intr_enable);
-
- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
- spin_unlock_irqrestore(&ehci->lock, flags);
+ rc = ehci_suspend(hcd, do_wakeup);
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
@@ -234,7 +219,6 @@ static int s5p_ehci_resume(struct device *dev)
{
struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
struct usb_hcd *hcd = s5p_ehci->hcd;
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct platform_device *pdev = to_platform_device(dev);
struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
@@ -246,44 +230,7 @@ static int s5p_ehci_resume(struct device *dev)
/* DMA burst Enable */
writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
- if (time_before(jiffies, ehci->next_statechange))
- msleep(100);
-
- /* Mark hardware accessible again as we are out of D3 state by now */
- set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
- if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
- int mask = INTR_MASK;
-
- ehci_prepare_ports_for_controller_resume(ehci);
- if (!hcd->self.root_hub->do_remote_wakeup)
- mask &= ~STS_PCD;
- ehci_writel(ehci, mask, &ehci->regs->intr_enable);
- ehci_readl(ehci, &ehci->regs->intr_enable);
- return 0;
- }
-
- usb_root_hub_lost_power(hcd->self.root_hub);
-
- (void) ehci_halt(ehci);
- (void) ehci_reset(ehci);
-
- /* emptying the schedule aborts any urbs */
- spin_lock_irq(&ehci->lock);
- if (ehci->reclaim)
- end_unlink_async(ehci);
- ehci_work(ehci);
- spin_unlock_irq(&ehci->lock);
-
- ehci_writel(ehci, ehci->command, &ehci->regs->command);
- ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
- ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
-
- /* here we "know" root ports should always stay powered */
- ehci_port_power(ehci, 1);
-
- ehci->rh_state = EHCI_RH_SUSPENDED;
-
+ ehci_resume(hcd, false);
return 0;
}
#else