Re: [PATCH 1/2] usb: otg: mxs-phy: Fix mx23 operation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Fabio Estevam,

> From: Mike Thompson <mpthompson@xxxxxxxxx>
> 
> 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 <mpthompson@xxxxxxxxx>
> Signed-off-by: Fabio Estevam <fabio.estevam@xxxxxxxxxxxxx>
> ---
>  drivers/usb/otg/mxs-phy.c |   34 +++++++++++++++++++++++++++++++---
>  1 file changed, 31 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
> index c1a67cb..8188380 100644
> --- 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,12 @@
>  #define BM_USBPHY_CTRL_ENUTMILEVEL2		BIT(14)
>  #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT	BIT(1)
> 
> +#define MXY_PHY_ENHOSTDISCONDETECT_DELAY	250
> +

Why 250 <what unit?> ? :)

>  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 +66,7 @@ static int mxs_phy_init(struct usb_phy *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 +81,34 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
>  	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));

Isn't this mx23 specific?

>  	return 0;
>  }
> @@ -91,6 +117,8 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy,
> int port) {
>  	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);

Best regards,
Marek Vasut
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux