diff options
author | Ramneek Mehresh <ramneek.mehresh@freescale.com> | 2014-12-02 04:59:36 (GMT) |
---|---|---|
committer | Xie Xiaobo <xiaobo.xie@nxp.com> | 2017-09-25 07:25:28 (GMT) |
commit | 2647518f5414f875a872eb76b2122668ca3627c1 (patch) | |
tree | fa887943f67ed307a5efefb1211f81bef11b7dec /drivers | |
parent | d0aa3d22a373a7884634b90177ace9b3eadb6001 (diff) | |
download | linux-2647518f5414f875a872eb76b2122668ca3627c1.tar.xz |
usb: pm: Fix sleep/deep-sleep issue for external ULPI phy
External ULPI phy registers are not to be restored
during normal sleep when phy power is not cut-off.
In addition, phy saving/restoration needs to happen only
during deep-sleep
Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
Signed-off-by: yinbo.zhu <yinbo.zhu@nxp.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index b475bc5..95d32b7 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -368,12 +368,12 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, portsc |= PORT_PTS_PTW; /* fall through */ case FSL_USB2_PHY_UTMI: + case FSL_USB2_PHY_UTMI_DUAL: if (pdata->has_fsl_erratum_a006918) { pr_warn("fsl-ehci: USB PHY clock invalid\n"); return -EINVAL; } - case FSL_USB2_PHY_UTMI_DUAL: /* PHY_CLK_VALID bit is de-featured from all controller * versions below 2.4 and is to be checked only for * internal UTMI phy @@ -549,15 +549,21 @@ static int ehci_fsl_save_context(struct usb_hcd *hcd) struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd->regs; + struct device *dev = hcd->self.controller; + struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); - phy_reg = ioremap(FSL_USB_PHY_ADDR, sizeof(struct ccsr_usb_phy)); - _memcpy_fromio((void *)&ehci_fsl->saved_phy_regs, phy_reg, + if (pdata->phy_mode == FSL_USB2_PHY_UTMI_DUAL) { + phy_reg = ioremap(FSL_USB_PHY_ADDR, sizeof(struct ccsr_usb_phy)); + _memcpy_fromio((void *)&ehci_fsl->saved_phy_regs, phy_reg, + sizeof(struct ccsr_usb_phy)); + } + _memcpy_fromio((void *)&ehci_fsl->saved_regs, ehci->regs, - sizeof(struct ehci_regs)); - ehci_fsl->usb_ctrl = in_be32(non_ehci + FSL_SOC_USB_CTRL); - return 0; + sizeof(struct ehci_regs)); + ehci_fsl->usb_ctrl = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + return 0; } /*Restore usb registers */ @@ -566,10 +572,15 @@ static int ehci_fsl_restore_context(struct usb_hcd *hcd) struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd->regs; + struct device *dev = hcd->self.controller; + struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev); - if (phy_reg) - _memcpy_toio(phy_reg, (void *)&ehci_fsl->saved_phy_regs, + if (pdata->phy_mode == FSL_USB2_PHY_UTMI_DUAL) { + if (phy_reg) + _memcpy_toio(phy_reg, + (void *)&ehci_fsl->saved_phy_regs, sizeof(struct ccsr_usb_phy)); + } _memcpy_toio(ehci->regs, (void *)&ehci_fsl->saved_regs, sizeof(struct ehci_regs)); @@ -752,11 +763,11 @@ static int ehci_fsl_drv_suspend(struct device *dev) ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), device_may_wakeup(dev)); - ehci_fsl_save_context(hcd); - if (!fsl_deep_sleep()) return 0; + ehci_fsl_save_context(hcd); + ehci_fsl->usb_ctrl = ioread32be(non_ehci + FSL_SOC_USB_CTRL); return 0; } @@ -768,7 +779,8 @@ static int ehci_fsl_drv_resume(struct device *dev) struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd->regs; - ehci_fsl_restore_context(hcd); + if (fsl_deep_sleep()) + ehci_fsl_restore_context(hcd); #if defined(CONFIG_FSL_USB2_OTG) || defined(CONFIG_FSL_USB2_OTG_MODULE) struct usb_bus host = hcd->self; |