summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRamneek Mehresh <ramneek.mehresh@freescale.com>2014-12-02 04:59:36 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-09-25 07:25:28 (GMT)
commit2647518f5414f875a872eb76b2122668ca3627c1 (patch)
treefa887943f67ed307a5efefb1211f81bef11b7dec
parentd0aa3d22a373a7884634b90177ace9b3eadb6001 (diff)
downloadlinux-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>
-rw-r--r--drivers/usb/host/ehci-fsl.c34
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;