diff options
author | Ramneek Mehresh <ramneek.mehresh@freescale.com> | 2014-12-02 04:59:36 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:41:44 (GMT) |
commit | 77e879488926d5d933ac0ca86883a88871f3401e (patch) | |
tree | 7d3ebe9255bf5e2281e75a680fbaabfea4d82a3a | |
parent | 61e11f34ac77956187358ff3b2984e9ecc6ac580 (diff) | |
download | linux-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>
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 27 | ||||
-rw-r--r-- | drivers/usb/host/fsl-mph-dr-of.c | 2 | ||||
-rw-r--r-- | include/linux/fsl_devices.h | 1 |
3 files changed, 23 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; diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 8c87c37..7308073 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -65,6 +65,7 @@ enum fsl_usb2_phy_modes { FSL_USB2_PHY_UTMI, FSL_USB2_PHY_UTMI_WIDE, FSL_USB2_PHY_SERIAL, + FSL_USB2_PHY_UTMI_DUAL, }; struct clk; |