Hi Peter,

On Fri, Dec 21, 2012 at 12:22 AM, Peter Chen <peter.c...@freescale.com> wrote:

> Current chipidea driver only considers disable stream mode at device
> mode, in fact, it may be related to below chipidea bug, and needs
> to consider all usb modes.
>
> STAR 9000378958
> Title: Non-Double Word Aligned Buffer Address Sometimes Causes Host to Hang 
> on OUT Retry
> www.synopsys.com/dw/star.php?c=dwc_usb2_hs_otg_controller&fixedIn=2.20a
>
> To fix this, we need to add CI13XXX_DISABLE_STREAMING after role->start/init.

Yes, setting CI13XXX_DISABLE_STREAMING inside ci_role_start does work.

If you think the patch below is fine I can properly submit it.

---
 drivers/usb/chipidea/ci.h |   39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index e25d126..7fe652a 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -18,6 +18,8 @@
 #include <linux/usb.h>
 #include <linux/usb/gadget.h>

+#define USBMODE_CI_SDIS       BIT(4)
+
 /******************************************************************************
  * DEFINE
  *****************************************************************************/
@@ -173,22 +175,6 @@ static inline struct ci_role_driver
*ci_role(struct ci13xxx *ci)
        return ci->roles[ci->role];
 }

-static inline int ci_role_start(struct ci13xxx *ci, enum ci_role role)
-{
-       int ret;
-
-       if (role >= CI_ROLE_END)
-               return -EINVAL;
-
-       if (!ci->roles[role])
-               return -ENXIO;
-
-       ret = ci->roles[role]->start(ci);
-       if (!ret)
-               ci->role = role;
-       return ret;
-}
-
 static inline void ci_role_stop(struct ci13xxx *ci)
 {
        enum ci_role role = ci->role;
@@ -307,6 +293,27 @@ static inline u32 hw_test_and_write(struct
ci13xxx *ci, enum ci13xxx_regs reg,
        return (val & mask) >> ffs_nr(mask);
 }

+
+static inline int ci_role_start(struct ci13xxx *ci, enum ci_role role)
+{
+       int ret;
+
+       if (role >= CI_ROLE_END)
+               return -EINVAL;
+
+       if (!ci->roles[role])
+               return -ENXIO;
+
+       ret = ci->roles[role]->start(ci);
+       if (!ret)
+               ci->role = role;
+
+       if (ci->platdata->flags & CI13XXX_DISABLE_STREAMING)
+               hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
+
+       return ret;
+}
+
 int hw_device_reset(struct ci13xxx *ci, u32 mode);

 int hw_port_test_set(struct ci13xxx *ci, u8 mode);
--
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to