summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorRamneek Mehresh <ramneek.mehresh@freescale.com>2014-11-26 17:29:05 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:41:33 (GMT)
commitcfacb4e6b8eb3889b5f36fd534f9e127268668f1 (patch)
tree54e52aa443334d28857493e3bebce00c5dc69e2b /drivers/usb
parent6686e31d26bffe9d7ad3aa12b33502d9340ab8b5 (diff)
downloadlinux-fsl-qoriq-cfacb4e6b8eb3889b5f36fd534f9e127268668f1.tar.xz
drivers:usb:fsl: Fix deep-sleep resume issue caused by usb
usb ip driver needs to save and restore all registers including phy registers across deep-sleep. This is required since latest changes in u-boot code doesn't re-init usb phy anymore during deep-sleep resume Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com> Signed-off-by: Suresh Gupta <suresh.gupta@freescale.com> Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com> Change-Id: Idc957b013a804bb4b12fa17836d0ae2371aeeed4 Reviewed-on: http://git.am.freescale.net:8181/24603 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Richard Schmitt <richard.schmitt@freescale.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ehci-fsl.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index f5ead5c9..87a4eb9 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -37,11 +37,45 @@
#include "ehci-fsl.h"
+#define FSL_USB_PHY_ADDR 0xffe214000
+
+struct ccsr_usb_port_ctrl {
+ u32 ctrl;
+ u32 drvvbuscfg;
+ u32 pwrfltcfg;
+ u32 sts;
+ u8 res_14[0xc];
+ u32 bistcfg;
+ u32 biststs;
+ u32 abistcfg;
+ u32 abiststs;
+ u8 res_30[0x10];
+ u32 xcvrprg;
+ u32 anaprg;
+ u32 anadrv;
+ u32 anasts;
+};
+
+struct ccsr_usb_phy {
+ u32 id;
+ struct ccsr_usb_port_ctrl port1;
+ u8 res_50[0xc];
+ u32 tvr;
+ u32 pllprg[4];
+ u8 res_70[0x4];
+ u32 anaccfg;
+ u32 dbg;
+ u8 res_7c[0x4];
+ struct ccsr_usb_port_ctrl port2;
+ u8 res_dc[0x334];
+};
+
struct ehci_fsl {
struct ehci_hcd ehci;
#ifdef CONFIG_PM
- struct ehci_regs *saved_regs;
+ struct ehci_regs saved_regs;
+ struct ccsr_usb_phy saved_phy_regs;
/* Saved USB PHY settings, need to restore after deep sleep. */
u32 usb_ctrl;
#endif
@@ -496,9 +530,9 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
}
-
-
#ifdef CONFIG_PM
+void __iomem *phy_reg;
+
/* save usb registers */
static int ehci_fsl_save_context(struct usb_hcd *hcd)
{
@@ -506,10 +540,10 @@ static int ehci_fsl_save_context(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
void __iomem *non_ehci = hcd->regs;
- ehci_fsl->saved_regs = kzalloc(sizeof(struct ehci_regs), GFP_KERNEL);
- if (!ehci_fsl->saved_regs)
- return -ENOMEM;
- _memcpy_fromio(ehci_fsl->saved_regs, ehci->regs,
+ 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);
return 0;
@@ -523,13 +557,13 @@ static int ehci_fsl_restore_context(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
void __iomem *non_ehci = hcd->regs;
- if (ehci_fsl->saved_regs) {
- _memcpy_toio(ehci->regs, ehci_fsl->saved_regs,
- sizeof(struct ehci_regs));
- iowrite32be(ehci_fsl->usb_ctrl, non_ehci + FSL_SOC_USB_CTRL);
- kfree(ehci_fsl->saved_regs);
- ehci_fsl->saved_regs = NULL;
- }
+ 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));
+ iowrite32be(ehci_fsl->usb_ctrl, non_ehci + FSL_SOC_USB_CTRL);
return 0;
}