i.MX35 has an issue that when USB DMA (SINGLE) transfers
are interrupted, the usb core can hang.

This patch implements the workaround described in ENGcm11601
by setting the AHB to use INCR transfers instead of SINGLE
transfers.

Signed-off-by: Bas Vermeulen <bas.vermeu...@blackstar.nl>
CC: Sasha Hauer <ker...@pengutronix.de>
CC: Alan Stern <st...@rowland.harvard.edu>
---
 drivers/usb/host/ehci-mxc.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index c7a9b31..1a00492 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -36,6 +36,7 @@
 static const char hcd_name[] = "ehci-mxc";
 
 #define ULPI_VIEWPORT_OFFSET   0x170
+#define SBUSCFG_OFFSET         0x090
 
 struct ehci_mxc_priv {
        struct clk *usbclk, *ahbclk, *phyclk;
@@ -43,8 +44,24 @@ struct ehci_mxc_priv {
 
 static struct hc_driver __read_mostly ehci_mxc_hc_driver;
 
+static int ehci_mxc_reset(struct usb_hcd *hcd)
+{
+       int retval;
+
+       retval = ehci_setup(hcd);
+       if (retval)
+               return retval;
+
+       /* workaround for ENGcm11601 */
+       if (of_machine_is_compatible("fsl,imx35"))
+               writel(0, hcd->regs + SBUSCFG_OFFSET);
+
+       return 0;
+}
+
 static const struct ehci_driver_overrides ehci_mxc_overrides __initconst = {
        .extra_priv_size =      sizeof(struct ehci_mxc_priv),
+       .reset =                ehci_mxc_reset,
 };
 
 static int ehci_mxc_drv_probe(struct platform_device *pdev)
-- 
1.9.1


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

--
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