This is a note to let you know that I've just added the patch titled

    usb: otg: mxs-phy: Fix mx23 operation

to the 3.6-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     usb-otg-mxs-phy-fix-mx23-operation.patch
and it can be found in the queue-3.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


>From 363366cf61c544ea476f3d220f43a95cb03014f5 Mon Sep 17 00:00:00 2001
From: Mike Thompson <[email protected]>
Date: Thu, 30 Aug 2012 18:26:25 -0300
Subject: usb: otg: mxs-phy: Fix mx23 operation

From: Mike Thompson <[email protected]>

commit 363366cf61c544ea476f3d220f43a95cb03014f5 upstream.

Currently mx23 fails to enumerate a USB device:

[ 1.300000] hub 1-0:1.0: unable to enumerate USB device on port 1
[ 1.520000] hub 1-0:1.0: unable to enumerate USB device on port 1
[ 1.740000] hub 1-0:1.0: unable to enumerate USB device on port 1
[ 1.960000] hub 1-0:1.0: unable to enumerate USB device on port 1
[ 2.180000] hub 1-0:1.0: unable to enumerate USB device on port 1

Use a kernel workqueue to asynchronously delay the setting of
ENHOSTDISCONDETECT bit until after higher level hub connect/reset processing
is complete.  Prematurely setting the bit prevents the connection
processing from completing and not setting it prevents disconnect from being
detected. No delay is needed for clearing of ENHOSTDISCONDETECT.

Successfully tested on mx23-olinuxino (micro, mini and maxi variants) and 
mx28evk.

Signed-off-by: Mike Thompson <[email protected]>
Signed-off-by: Fabio Estevam <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 drivers/usb/otg/mxs-phy.c |   38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/workqueue.h>
 
 #define DRIVER_NAME "mxs_phy"
 
@@ -34,9 +35,16 @@
 #define BM_USBPHY_CTRL_ENUTMILEVEL2            BIT(14)
 #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT      BIT(1)
 
+/*
+ * Amount of delay in miliseconds to safely enable ENHOSTDISCONDETECT bit
+ * so that connection and reset processing can be completed for the root hub.
+ */
+#define MXY_PHY_ENHOSTDISCONDETECT_DELAY       250
+
 struct mxs_phy {
        struct usb_phy phy;
        struct clk *clk;
+       struct delayed_work enhostdiscondetect_work;
 };
 
 #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
@@ -62,6 +70,7 @@ static int mxs_phy_init(struct usb_phy *
 
        clk_prepare_enable(mxs_phy->clk);
        mxs_phy_hw_init(mxs_phy);
+       INIT_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, NULL);
 
        return 0;
 }
@@ -76,13 +85,34 @@ static void mxs_phy_shutdown(struct usb_
        clk_disable_unprepare(mxs_phy->clk);
 }
 
+static void mxs_phy_enhostdiscondetect_delay(struct work_struct *ws)
+{
+       struct mxs_phy *mxs_phy = container_of(ws, struct mxs_phy,
+                                               enhostdiscondetect_work.work);
+
+       /* Enable HOSTDISCONDETECT after delay. */
+       dev_dbg(mxs_phy->phy.dev, "Setting ENHOSTDISCONDETECT\n");
+       writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+                               mxs_phy->phy.io_priv + HW_USBPHY_CTRL_SET);
+}
+
 static int mxs_phy_on_connect(struct usb_phy *phy, int port)
 {
+       struct mxs_phy *mxs_phy = to_mxs_phy(phy);
+
        dev_dbg(phy->dev, "Connect on port %d\n", port);
 
-       mxs_phy_hw_init(to_mxs_phy(phy));
-       writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
-                       phy->io_priv + HW_USBPHY_CTRL_SET);
+       mxs_phy_hw_init(mxs_phy);
+
+       /*
+        * Delay enabling ENHOSTDISCONDETECT so that connection and
+        * reset processing can be completed for the root hub.
+        */
+       dev_dbg(phy->dev, "Delaying setting ENHOSTDISCONDETECT\n");
+       PREPARE_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work,
+                       mxs_phy_enhostdiscondetect_delay);
+       schedule_delayed_work(&mxs_phy->enhostdiscondetect_work,
+                       msecs_to_jiffies(MXY_PHY_ENHOSTDISCONDETECT_DELAY));
 
        return 0;
 }
@@ -91,6 +121,8 @@ static int mxs_phy_on_disconnect(struct
 {
        dev_dbg(phy->dev, "Disconnect on port %d\n", port);
 
+       /* No need to delay before clearing ENHOSTDISCONDETECT. */
+       dev_dbg(phy->dev, "Clearing ENHOSTDISCONDETECT\n");
        writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
                        phy->io_priv + HW_USBPHY_CTRL_CLR);
 


Patches currently in stable-queue which might be from [email protected] are

queue-3.6/usb-otg-mxs-phy-fix-mx23-operation.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to