summaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorRamneek Mehresh <ramneek.mehresh@freescale.com>2014-12-02 04:59:36 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:41:44 (GMT)
commit77e879488926d5d933ac0ca86883a88871f3401e (patch)
tree7d3ebe9255bf5e2281e75a680fbaabfea4d82a3a /drivers/usb/host
parent61e11f34ac77956187358ff3b2984e9ecc6ac580 (diff)
downloadlinux-fsl-qoriq-77e879488926d5d933ac0ca86883a88871f3401e.tar.xz
drivers: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> Change-Id: I840724ff3cf4e85582e2e1c73b1ff9798dfd7304 Reviewed-on: http://git.am.freescale.net:8181/24849 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Nikhil Badola <nikhil.badola@freescale.com> Reviewed-by: Matthew Weigel <Matthew.Weigel@freescale.com>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-fsl.c27
-rw-r--r--drivers/usb/host/fsl-mph-dr-of.c2
2 files changed, 22 insertions, 7 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 87a4eb9..2f319db 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -370,6 +370,7 @@ 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;
@@ -539,10 +540,16 @@ 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 = ioread32be(non_ehci + FSL_SOC_USB_CTRL);
@@ -556,10 +563,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));
@@ -744,11 +756,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;
}
@@ -760,7 +772,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;
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index 3bb0cd0..afbee80 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -70,6 +70,8 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
return FSL_USB2_PHY_UTMI;
if (!strcasecmp(phy_type, "utmi_wide"))
return FSL_USB2_PHY_UTMI_WIDE;
+ if (!strcasecmp(phy_type, "utmi_dual"))
+ return FSL_USB2_PHY_UTMI_DUAL;
if (!strcasecmp(phy_type, "serial"))
return FSL_USB2_PHY_SERIAL;