]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00221716-01 Mx6 USB host: set disconnect bit should wait for resume finished
authormake shi <b15407@freescale.com>
Tue, 28 Aug 2012 09:12:07 +0000 (17:12 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:35:20 +0000 (08:35 +0200)
For i.MX6DLTO1.1 and i.MX6DQTO1.2, the disconnection-bit can only be set after
the resume finished, otherwise, the remote-wake-up may fail. Because if the
device not switch to High-Speed 45ohm termination resistors mode, when the
disconnection  detection bit is set the disconnection detection circuit will
detect a high speed disconnection by mistake.

Signed-off-by: make shi <b15407@freescale.com>
arch/arm/mach-mx6/usb_dr.c
arch/arm/mach-mx6/usb_h1.c

index 8cfcb27c7594be76fbb431c25a0a4cbb62cf5b79..8fe9700a658f0f2421cd9bef6feeccb6aacb5f3d 100644 (file)
@@ -442,18 +442,18 @@ static void _host_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
 {
        u32 index = 0;
 
-       if ((UOG_PORTSC1 & (3 << 26)) != (2 << 26))
+       if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
                return ;
-
        while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
                        && (index < 1000)) {
                udelay(500);
                index++;
        }
-
        if (index >= 1000)
-               printk(KERN_INFO "%s big error\n", __func__);
-
+               printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+               __func__, __LINE__);
+       /* We should add some delay to wait for the device switch to
+         * High-Speed 45ohm termination resistors mode. */
        udelay(500);
        fsl_platform_otg_set_usb_phy_dis(pdata, 1);
 }
@@ -469,9 +469,24 @@ static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
 
 static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
 {
+       u32 index = 0;
+
        /*for mx6sl ,we do not need any sw fix*/
        if (cpu_is_mx6sl())
                return ;
+       if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+               return ;
+       while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+                       && (index < 1000)) {
+               udelay(500);
+               index++;
+       }
+       if (index >= 1000)
+               printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+               __func__, __LINE__);
+       /* We should add some delay to wait for the device switch to
+         * High-Speed 45ohm termination resistors mode. */
+       udelay(500);
        __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
                MX6_IO_ADDRESS(pdata->phy_regs)
                + HW_USBPHY_CTRL_SET);
index 3e2f50ab6b55bc0930f29203beab6af3f1535a8a..bece29f7d44b6f660efd157289d37c64134e6b95 100644 (file)
@@ -244,18 +244,18 @@ static void usbh1_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
 {
        u32 index = 0;
 
-       if ((UH1_PORTSC1 & (3 << 26)) != (2 << 26))
+       if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
                return ;
-
        while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
                        && (index < 1000)) {
                udelay(500);
                index++;
        }
-
        if (index >= 1000)
-               printk(KERN_INFO "%s big error\n", __func__);
-
+               printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+               __func__, __LINE__);
+       /* We should add some delay to wait for the device switch to
+         * High-Speed 45ohm termination resistors mode. */
        udelay(500);
        fsl_platform_h1_set_usb_phy_dis(pdata, 1);
 }
@@ -272,9 +272,24 @@ static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
 
 static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
 {
+       u32 index = 0;
+
        /*for mx6sl ,we do not need any sw fix*/
        if (cpu_is_mx6sl())
                return ;
+       if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+               return ;
+       while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+                       && (index < 1000)) {
+               udelay(500);
+               index++;
+       }
+       if (index >= 1000)
+               printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+               __func__, __LINE__);
+       /* We should add some delay to wait for the device switch to
+         * High-Speed 45ohm termination resistors mode. */
+       udelay(500);
        __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
                MX6_IO_ADDRESS(pdata->phy_regs)
                + HW_USBPHY_CTRL_SET);