linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
@ 2016-05-13 10:24 Baolin Wang
  2016-05-13 10:40 ` Felipe Balbi
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-13 10:24 UTC (permalink / raw)
  To: balbi, gregkh; +Cc: broonie, linux-usb, linux-kernel, baolin.wang

Currently on some platforms, the gadget device can be power off to save power
when the Vbus is off, which means no cable plugging in now. In this situation
we should defer starting the gadget until the gadget device is power on by
connecting host.

Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
 drivers/usb/dwc3/core.c          |    5 +-
 drivers/usb/dwc3/core.h          |   14 ++++
 drivers/usb/dwc3/gadget.c        |  144 ++++++++++++++++++++++++++++++--------
 drivers/usb/dwc3/platform_data.h |    1 +
 4 files changed, 131 insertions(+), 33 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 34277ce..825462a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -109,7 +109,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
  * dwc3_soft_reset - Issue soft reset
  * @dwc: Pointer to our controller context structure
  */
-static int dwc3_soft_reset(struct dwc3 *dwc)
+int dwc3_soft_reset(struct dwc3 *dwc)
 {
 	unsigned long timeout;
 	u32 reg;
@@ -253,7 +253,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
  *
  * Returns 0 on success otherwise negative errno.
  */
-static int dwc3_event_buffers_setup(struct dwc3 *dwc)
+int dwc3_event_buffers_setup(struct dwc3 *dwc)
 {
 	struct dwc3_event_buffer	*evt;
 	int				n;
@@ -948,6 +948,7 @@ static int dwc3_probe(struct platform_device *pdev)
 
 		dwc->hsphy_interface = pdata->hsphy_interface;
 		fladj = pdata->fladj_value;
+		dwc->can_save_power = pdata->can_save_power;
 	}
 
 	dwc->lpm_nyet_threshold = lpm_nyet_threshold;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 6254b2f..dada5c6 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -734,6 +734,9 @@ struct dwc3_scratchpad_array {
  * 	1	- -3.5dB de-emphasis
  * 	2	- No de-emphasis
  * 	3	- Reserved
+ * @can_save_power: set if the gadget will power off when no cable plug in.
+ * @need_restart: set if we need to restart the gadget.
+ * @cable_connected: set if one usb cable is plugging in.
  */
 struct dwc3 {
 	struct usb_ctrlrequest	*ctrl_req;
@@ -876,6 +879,9 @@ struct dwc3 {
 
 	unsigned		tx_de_emphasis_quirk:1;
 	unsigned		tx_de_emphasis:2;
+	unsigned		can_save_power:1;
+	unsigned		need_restart:1;
+	unsigned		cable_connected:1;
 };
 
 /* -------------------------------------------------------------------------- */
@@ -1026,6 +1032,8 @@ struct dwc3_gadget_ep_cmd_params {
 /* prototypes */
 void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
 int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
+int dwc3_soft_reset(struct dwc3 *dwc);
+int dwc3_event_buffers_setup(struct dwc3 *dwc);
 
 /* check whether we are on the DWC_usb31 core */
 static inline bool dwc3_is_usb31(struct dwc3 *dwc)
@@ -1052,6 +1060,8 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
 int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
 int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param);
+void dwc3_gadget_connect(struct dwc3 *dwc);
+void dwc3_gadget_disconnect(struct dwc3 *dwc);
 #else
 static inline int dwc3_gadget_init(struct dwc3 *dwc)
 { return 0; }
@@ -1071,6 +1081,10 @@ static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
 static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc,
 		int cmd, u32 param)
 { return 0; }
+static inline void dwc3_gadget_connect(struct dwc3 *dwc)
+{ }
+static inline void dwc3_gadget_disconnect(struct dwc3 *dwc)
+{ }
 #endif
 
 /* power management interface */
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 8e4a1b1..90805f9 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1512,13 +1512,75 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
 	return 0;
 }
 
+void dwc3_gadget_connect(struct dwc3 *dwc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dwc->cable_connected = true;
+	spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
+void dwc3_gadget_disconnect(struct dwc3 *dwc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	dwc->cable_connected = false;
+	spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
+static bool dwc3_gadget_is_connected(struct dwc3 *dwc)
+{
+	/*
+	 * If the gadget is always power on, then no need to check if the
+	 * cable is plugin or not.
+	 */
+	if (!dwc->can_save_power)
+		return true;
+
+	return dwc->cable_connected;
+}
+
+static int __dwc3_gadget_start(struct dwc3 *dwc);
+
 static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
 {
 	u32			reg;
 	u32			timeout = 500;
+	int			ret;
+
+	if (!dwc3_gadget_is_connected(dwc) || !dwc->gadget_driver)
+		return 0;
 
 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 	if (is_on) {
+		if (dwc->need_restart) {
+			/*
+			 * We need to reset the device firstly when the device
+			 * is power on.
+			 */
+			ret = dwc3_soft_reset(dwc);
+			if (ret)
+				return ret;
+
+			/*
+			 * After resetting the device, it need to re-setup the
+			 * event buffer.
+			 */
+			ret = dwc3_event_buffers_setup(dwc);
+			if (ret) {
+				dev_err(dwc->dev,
+					"failed to setup event buffers\n");
+				return ret;
+			}
+
+			/* Start the gadget */
+			ret = __dwc3_gadget_start(dwc);
+			if (ret)
+				return ret;
+		}
+
 		if (dwc->revision <= DWC3_REVISION_187A) {
 			reg &= ~DWC3_DCTL_TRGTULST_MASK;
 			reg |= DWC3_DCTL_TRGTULST_RX_DET;
@@ -1608,37 +1670,12 @@ static void dwc3_gadget_disable_irq(struct dwc3 *dwc)
 static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
 static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc);
 
-static int dwc3_gadget_start(struct usb_gadget *g,
-		struct usb_gadget_driver *driver)
+static int __dwc3_gadget_start(struct dwc3 *dwc)
 {
-	struct dwc3		*dwc = gadget_to_dwc(g);
 	struct dwc3_ep		*dep;
-	unsigned long		flags;
 	int			ret = 0;
-	int			irq;
 	u32			reg;
 
-	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
-	ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
-			IRQF_SHARED, "dwc3", dwc);
-	if (ret) {
-		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
-				irq, ret);
-		goto err0;
-	}
-
-	spin_lock_irqsave(&dwc->lock, flags);
-
-	if (dwc->gadget_driver) {
-		dev_err(dwc->dev, "%s is already bound to %s\n",
-				dwc->gadget.name,
-				dwc->gadget_driver->driver.name);
-		ret = -EBUSY;
-		goto err1;
-	}
-
-	dwc->gadget_driver	= driver;
-
 	reg = dwc3_readl(dwc->regs, DWC3_DCFG);
 	reg &= ~(DWC3_DCFG_SPEED_MASK);
 
@@ -1690,7 +1727,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 			false);
 	if (ret) {
 		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
-		goto err2;
+		return ret;
 	}
 
 	dep = dwc->eps[1];
@@ -1698,7 +1735,8 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 			false);
 	if (ret) {
 		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
-		goto err3;
+		__dwc3_gadget_ep_disable(dwc->eps[0]);
+		return ret;
 	}
 
 	/* begin to receive SETUP packets */
@@ -1707,13 +1745,57 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 
 	dwc3_gadget_enable_irq(dwc);
 
+	return 0;
+}
+
+static int dwc3_gadget_start(struct usb_gadget *g,
+		struct usb_gadget_driver *driver)
+{
+	struct dwc3		*dwc = gadget_to_dwc(g);
+	unsigned long		flags;
+	int			ret = 0;
+	int			irq;
+
+	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
+	ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
+			IRQF_SHARED, "dwc3", dwc);
+	if (ret) {
+		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
+				irq, ret);
+		goto err0;
+	}
+
+	spin_lock_irqsave(&dwc->lock, flags);
+
+	if (dwc->gadget_driver) {
+		dev_err(dwc->dev, "%s is already bound to %s\n",
+				dwc->gadget.name,
+				dwc->gadget_driver->driver.name);
+		ret = -EBUSY;
+		goto err1;
+	}
+
+	dwc->gadget_driver	= driver;
+
+	/*
+	 * If the gadget can be power off when there is no cable plug in, we
+	 * need to check if the device power is on or not. If not, we should
+	 * not access the device registers.
+	 */
+	if (!dwc3_gadget_is_connected(dwc)) {
+		dwc->need_restart = 1;
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		return 0;
+	}
+
+	ret = __dwc3_gadget_start(dwc);
+	if (ret)
+		goto err2;
+
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	return 0;
 
-err3:
-	__dwc3_gadget_ep_disable(dwc->eps[0]);
-
 err2:
 	dwc->gadget_driver = NULL;
 
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index 2bb4d3a..7e15266 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -46,6 +46,7 @@ struct dwc3_platform_data {
 
 	unsigned tx_de_emphasis_quirk:1;
 	unsigned tx_de_emphasis:2;
+	unsigned can_save_power:1;
 
 	u32 fladj_value;
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-13 10:24 [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on Baolin Wang
@ 2016-05-13 10:40 ` Felipe Balbi
  2016-05-13 11:34   ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2016-05-13 10:40 UTC (permalink / raw)
  To: Baolin Wang, gregkh; +Cc: broonie, linux-usb, linux-kernel, baolin.wang

[-- Attachment #1: Type: text/plain, Size: 8357 bytes --]


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
> Currently on some platforms, the gadget device can be power off to
> save power when the Vbus is off, which means no cable plugging in
> now. In this situation we should defer starting the gadget until the
> gadget device is power on by connecting host.

okay, you need to be a looooooooooot more specific about this. From a
basic look at the patch, there's no way I'll ever accept it, see below

> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
> ---
>  drivers/usb/dwc3/core.c          |    5 +-
>  drivers/usb/dwc3/core.h          |   14 ++++
>  drivers/usb/dwc3/gadget.c        |  144 ++++++++++++++++++++++++++++++--------
>  drivers/usb/dwc3/platform_data.h |    1 +
>  4 files changed, 131 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 34277ce..825462a 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -109,7 +109,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
>   * dwc3_soft_reset - Issue soft reset
>   * @dwc: Pointer to our controller context structure
>   */
> -static int dwc3_soft_reset(struct dwc3 *dwc)
> +int dwc3_soft_reset(struct dwc3 *dwc)

this *CANNOT* and *WILL* not be exposed to anything other than
core.c. We don't want anybody else resetting dwc3 willy-nilly.

> @@ -253,7 +253,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
>   *
>   * Returns 0 on success otherwise negative errno.
>   */
> -static int dwc3_event_buffers_setup(struct dwc3 *dwc)
> +int dwc3_event_buffers_setup(struct dwc3 *dwc)

likewise

> @@ -948,6 +948,7 @@ static int dwc3_probe(struct platform_device *pdev)
>  
>  		dwc->hsphy_interface = pdata->hsphy_interface;
>  		fladj = pdata->fladj_value;
> +		dwc->can_save_power = pdata->can_save_power;

sounds like a pointless flag IMHO.

>  	}
>  
>  	dwc->lpm_nyet_threshold = lpm_nyet_threshold;
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index 6254b2f..dada5c6 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -734,6 +734,9 @@ struct dwc3_scratchpad_array {
>   * 	1	- -3.5dB de-emphasis
>   * 	2	- No de-emphasis
>   * 	3	- Reserved
> + * @can_save_power: set if the gadget will power off when no cable plug in.

nope

> + * @need_restart: set if we need to restart the gadget.

why does it need restart? Why is dwc3 powered off? Who powers it off?

This looks like a *really* bad power management implementation. Do you
have hibernation enabled? Do you have Clock gating enabled? Which dwc3
version are you using? How was it configured?

> + * @cable_connected: set if one usb cable is plugging in.

not necessary, we already infer that from RUN/STOP and reset interrupt.

> @@ -876,6 +879,9 @@ struct dwc3 {
>  
>  	unsigned		tx_de_emphasis_quirk:1;
>  	unsigned		tx_de_emphasis:2;
> +	unsigned		can_save_power:1;
> +	unsigned		need_restart:1;
> +	unsigned		cable_connected:1;
>  };
>  
>  /* -------------------------------------------------------------------------- */
> @@ -1026,6 +1032,8 @@ struct dwc3_gadget_ep_cmd_params {
>  /* prototypes */
>  void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
>  int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
> +int dwc3_soft_reset(struct dwc3 *dwc);
> +int dwc3_event_buffers_setup(struct dwc3 *dwc);

makes me cringe

> @@ -1052,6 +1060,8 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
>  int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
>  		unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
>  int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param);
> +void dwc3_gadget_connect(struct dwc3 *dwc);
> +void dwc3_gadget_disconnect(struct dwc3 *dwc);

hell no

>  #else
>  static inline int dwc3_gadget_init(struct dwc3 *dwc)
>  { return 0; }
> @@ -1071,6 +1081,10 @@ static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
>  static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc,
>  		int cmd, u32 param)
>  { return 0; }
> +static inline void dwc3_gadget_connect(struct dwc3 *dwc)
> +{ }
> +static inline void dwc3_gadget_disconnect(struct dwc3 *dwc)
> +{ }
>  #endif
>  
>  /* power management interface */
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 8e4a1b1..90805f9 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -1512,13 +1512,75 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
>  	return 0;
>  }
>  
> +void dwc3_gadget_connect(struct dwc3 *dwc)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dwc->lock, flags);
> +	dwc->cable_connected = true;
> +	spin_unlock_irqrestore(&dwc->lock, flags);
> +}
> +
> +void dwc3_gadget_disconnect(struct dwc3 *dwc)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dwc->lock, flags);
> +	dwc->cable_connected = false;
> +	spin_unlock_irqrestore(&dwc->lock, flags);
> +}
> +

nope

> +static bool dwc3_gadget_is_connected(struct dwc3 *dwc)
> +{
> +	/*
> +	 * If the gadget is always power on, then no need to check if the
> +	 * cable is plugin or not.
> +	 */
> +	if (!dwc->can_save_power)
> +		return true;

this is wrong! Really, really wrong! If cable is detached, you're saying
it's always attached. No. Don't do it. Don't lie to the driver.

> +static int __dwc3_gadget_start(struct dwc3 *dwc);
> +
>  static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
>  {
>  	u32			reg;
>  	u32			timeout = 500;
> +	int			ret;
> +
> +	if (!dwc3_gadget_is_connected(dwc) || !dwc->gadget_driver)
> +		return 0;
>  
>  	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
>  	if (is_on) {
> +		if (dwc->need_restart) {
> +			/*
> +			 * We need to reset the device firstly when the device
> +			 * is power on.
> +			 */
> +			ret = dwc3_soft_reset(dwc);
> +			if (ret)
> +				return ret;
> +
> +			/*
> +			 * After resetting the device, it need to re-setup the
> +			 * event buffer.
> +			 */
> +			ret = dwc3_event_buffers_setup(dwc);
> +			if (ret) {
> +				dev_err(dwc->dev,
> +					"failed to setup event buffers\n");
> +				return ret;
> +			}
> +
> +			/* Start the gadget */
> +			ret = __dwc3_gadget_start(dwc);
> +			if (ret)
> +				return ret;
> +		}

no way

> +static int dwc3_gadget_start(struct usb_gadget *g,
> +		struct usb_gadget_driver *driver)
> +{
> +	struct dwc3		*dwc = gadget_to_dwc(g);
> +	unsigned long		flags;
> +	int			ret = 0;
> +	int			irq;
> +
> +	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
> +	ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
> +			IRQF_SHARED, "dwc3", dwc);
> +	if (ret) {
> +		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
> +				irq, ret);
> +		goto err0;
> +	}
> +
> +	spin_lock_irqsave(&dwc->lock, flags);
> +
> +	if (dwc->gadget_driver) {
> +		dev_err(dwc->dev, "%s is already bound to %s\n",
> +				dwc->gadget.name,
> +				dwc->gadget_driver->driver.name);
> +		ret = -EBUSY;
> +		goto err1;
> +	}
> +
> +	dwc->gadget_driver	= driver;
> +
> +	/*
> +	 * If the gadget can be power off when there is no cable plug in, we
> +	 * need to check if the device power is on or not. If not, we should
> +	 * not access the device registers.
> +	 */
> +	if (!dwc3_gadget_is_connected(dwc)) {
> +		dwc->need_restart = 1;
> +		spin_unlock_irqrestore(&dwc->lock, flags);
> +		return 0;
> +	}
> +
> +	ret = __dwc3_gadget_start(dwc);
> +	if (ret)
> +		goto err2;
> +

this is similar to a patch I wrote to improve system suspend/resume (not
runtime). See:

https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=dwc3-fix-suspend&id=d1c2d86ef61b8f7ac793036aee9d501fa44d9b8a

https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=dwc3-fix-suspend&id=b6dc23f16389ee8803aba6a4c0265aac547f9c57

https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=dwc3-fix-suspend&id=7c38518f5ea748ecccce651d899cf7714dfb653f

I haven't sent because I didn't finish testing yet

Anyway, which platform are you dealing with? Why is dwc3 off while VBUS
is off? How do you handle host mode?

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-13 10:40 ` Felipe Balbi
@ 2016-05-13 11:34   ` Baolin Wang
  2016-05-13 12:09     ` Felipe Balbi
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-13 11:34 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

Hi Felipe,

On 13 May 2016 at 18:40, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>> Currently on some platforms, the gadget device can be power off to
>> save power when the Vbus is off, which means no cable plugging in
>> now. In this situation we should defer starting the gadget until the
>> gadget device is power on by connecting host.
>
> okay, you need to be a looooooooooot more specific about this. From a
> basic look at the patch, there's no way I'll ever accept it, see below
>
>> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
>> ---
>>  drivers/usb/dwc3/core.c          |    5 +-
>>  drivers/usb/dwc3/core.h          |   14 ++++
>>  drivers/usb/dwc3/gadget.c        |  144 ++++++++++++++++++++++++++++++--------
>>  drivers/usb/dwc3/platform_data.h |    1 +
>>  4 files changed, 131 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 34277ce..825462a 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -109,7 +109,7 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
>>   * dwc3_soft_reset - Issue soft reset
>>   * @dwc: Pointer to our controller context structure
>>   */
>> -static int dwc3_soft_reset(struct dwc3 *dwc)
>> +int dwc3_soft_reset(struct dwc3 *dwc)
>
> this *CANNOT* and *WILL* not be exposed to anything other than
> core.c. We don't want anybody else resetting dwc3 willy-nilly.
>
>> @@ -253,7 +253,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
>>   *
>>   * Returns 0 on success otherwise negative errno.
>>   */
>> -static int dwc3_event_buffers_setup(struct dwc3 *dwc)
>> +int dwc3_event_buffers_setup(struct dwc3 *dwc)
>
> likewise
>
>> @@ -948,6 +948,7 @@ static int dwc3_probe(struct platform_device *pdev)
>>
>>               dwc->hsphy_interface = pdata->hsphy_interface;
>>               fladj = pdata->fladj_value;
>> +             dwc->can_save_power = pdata->can_save_power;
>
> sounds like a pointless flag IMHO.
>
>>       }
>>
>>       dwc->lpm_nyet_threshold = lpm_nyet_threshold;
>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>> index 6254b2f..dada5c6 100644
>> --- a/drivers/usb/dwc3/core.h
>> +++ b/drivers/usb/dwc3/core.h
>> @@ -734,6 +734,9 @@ struct dwc3_scratchpad_array {
>>   *   1       - -3.5dB de-emphasis
>>   *   2       - No de-emphasis
>>   *   3       - Reserved
>> + * @can_save_power: set if the gadget will power off when no cable plug in.
>
> nope
>
>> + * @need_restart: set if we need to restart the gadget.
>
> why does it need restart? Why is dwc3 powered off? Who powers it off?

Because when the dwc3 Vbus is off (no cable pluging in now),
especially for some mobile device, the system need to power off the
dwc3 to save power in this situation.

>
> This looks like a *really* bad power management implementation. Do you
> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
> version are you using? How was it configured?

This is not hibernation, we want to power off the dwc3 to save power
when no cable plugging in. Yes, we have clock gating, at this
situation we will disable the clock and shutdown the phy to save
power. For mobile device, most time no cable plugging in, so we need
to think about the power consuming. How do you think this requirement?
Thanks.

>
>> + * @cable_connected: set if one usb cable is plugging in.
>
> not necessary, we already infer that from RUN/STOP and reset interrupt.
>
>> @@ -876,6 +879,9 @@ struct dwc3 {
>>
>>       unsigned                tx_de_emphasis_quirk:1;
>>       unsigned                tx_de_emphasis:2;
>> +     unsigned                can_save_power:1;
>> +     unsigned                need_restart:1;
>> +     unsigned                cable_connected:1;
>>  };
>>
>>  /* -------------------------------------------------------------------------- */
>> @@ -1026,6 +1032,8 @@ struct dwc3_gadget_ep_cmd_params {
>>  /* prototypes */
>>  void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
>>  int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
>> +int dwc3_soft_reset(struct dwc3 *dwc);
>> +int dwc3_event_buffers_setup(struct dwc3 *dwc);
>
> makes me cringe
>
>> @@ -1052,6 +1060,8 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state);
>>  int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
>>               unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
>>  int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned cmd, u32 param);
>> +void dwc3_gadget_connect(struct dwc3 *dwc);
>> +void dwc3_gadget_disconnect(struct dwc3 *dwc);
>
> hell no
>
>>  #else
>>  static inline int dwc3_gadget_init(struct dwc3 *dwc)
>>  { return 0; }
>> @@ -1071,6 +1081,10 @@ static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
>>  static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc,
>>               int cmd, u32 param)
>>  { return 0; }
>> +static inline void dwc3_gadget_connect(struct dwc3 *dwc)
>> +{ }
>> +static inline void dwc3_gadget_disconnect(struct dwc3 *dwc)
>> +{ }
>>  #endif
>>
>>  /* power management interface */
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 8e4a1b1..90805f9 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -1512,13 +1512,75 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
>>       return 0;
>>  }
>>
>> +void dwc3_gadget_connect(struct dwc3 *dwc)
>> +{
>> +     unsigned long flags;
>> +
>> +     spin_lock_irqsave(&dwc->lock, flags);
>> +     dwc->cable_connected = true;
>> +     spin_unlock_irqrestore(&dwc->lock, flags);
>> +}
>> +
>> +void dwc3_gadget_disconnect(struct dwc3 *dwc)
>> +{
>> +     unsigned long flags;
>> +
>> +     spin_lock_irqsave(&dwc->lock, flags);
>> +     dwc->cable_connected = false;
>> +     spin_unlock_irqrestore(&dwc->lock, flags);
>> +}
>> +
>
> nope
>
>> +static bool dwc3_gadget_is_connected(struct dwc3 *dwc)
>> +{
>> +     /*
>> +      * If the gadget is always power on, then no need to check if the
>> +      * cable is plugin or not.
>> +      */
>> +     if (!dwc->can_save_power)
>> +             return true;
>
> this is wrong! Really, really wrong! If cable is detached, you're saying
> it's always attached. No. Don't do it. Don't lie to the driver.
>
>> +static int __dwc3_gadget_start(struct dwc3 *dwc);
>> +
>>  static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
>>  {
>>       u32                     reg;
>>       u32                     timeout = 500;
>> +     int                     ret;
>> +
>> +     if (!dwc3_gadget_is_connected(dwc) || !dwc->gadget_driver)
>> +             return 0;
>>
>>       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
>>       if (is_on) {
>> +             if (dwc->need_restart) {
>> +                     /*
>> +                      * We need to reset the device firstly when the device
>> +                      * is power on.
>> +                      */
>> +                     ret = dwc3_soft_reset(dwc);
>> +                     if (ret)
>> +                             return ret;
>> +
>> +                     /*
>> +                      * After resetting the device, it need to re-setup the
>> +                      * event buffer.
>> +                      */
>> +                     ret = dwc3_event_buffers_setup(dwc);
>> +                     if (ret) {
>> +                             dev_err(dwc->dev,
>> +                                     "failed to setup event buffers\n");
>> +                             return ret;
>> +                     }
>> +
>> +                     /* Start the gadget */
>> +                     ret = __dwc3_gadget_start(dwc);
>> +                     if (ret)
>> +                             return ret;
>> +             }
>
> no way
>
>> +static int dwc3_gadget_start(struct usb_gadget *g,
>> +             struct usb_gadget_driver *driver)
>> +{
>> +     struct dwc3             *dwc = gadget_to_dwc(g);
>> +     unsigned long           flags;
>> +     int                     ret = 0;
>> +     int                     irq;
>> +
>> +     irq = platform_get_irq(to_platform_device(dwc->dev), 0);
>> +     ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
>> +                     IRQF_SHARED, "dwc3", dwc);
>> +     if (ret) {
>> +             dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
>> +                             irq, ret);
>> +             goto err0;
>> +     }
>> +
>> +     spin_lock_irqsave(&dwc->lock, flags);
>> +
>> +     if (dwc->gadget_driver) {
>> +             dev_err(dwc->dev, "%s is already bound to %s\n",
>> +                             dwc->gadget.name,
>> +                             dwc->gadget_driver->driver.name);
>> +             ret = -EBUSY;
>> +             goto err1;
>> +     }
>> +
>> +     dwc->gadget_driver      = driver;
>> +
>> +     /*
>> +      * If the gadget can be power off when there is no cable plug in, we
>> +      * need to check if the device power is on or not. If not, we should
>> +      * not access the device registers.
>> +      */
>> +     if (!dwc3_gadget_is_connected(dwc)) {
>> +             dwc->need_restart = 1;
>> +             spin_unlock_irqrestore(&dwc->lock, flags);
>> +             return 0;
>> +     }
>> +
>> +     ret = __dwc3_gadget_start(dwc);
>> +     if (ret)
>> +             goto err2;
>> +
>
> this is similar to a patch I wrote to improve system suspend/resume (not
> runtime). See:
>
> https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=dwc3-fix-suspend&id=d1c2d86ef61b8f7ac793036aee9d501fa44d9b8a
>
> https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=dwc3-fix-suspend&id=b6dc23f16389ee8803aba6a4c0265aac547f9c57
>
> https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=dwc3-fix-suspend&id=7c38518f5ea748ecccce651d899cf7714dfb653f
>
> I haven't sent because I didn't finish testing yet

OK.

>
> Anyway, which platform are you dealing with? Why is dwc3 off while VBUS
> is off? How do you handle host mode?

On Spreadtrum platform, for thinking about some mobile devices with
strict power management. This is just for gadget mode, we don't power
off the dwc3 when it is host mode. Thanks.

>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-13 11:34   ` Baolin Wang
@ 2016-05-13 12:09     ` Felipe Balbi
  2016-05-13 12:35       ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2016-05-13 12:09 UTC (permalink / raw)
  To: Baolin Wang; +Cc: Greg KH, Mark Brown, USB, LKML

[-- Attachment #1: Type: text/plain, Size: 2100 bytes --]


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>>> index 6254b2f..dada5c6 100644
>>> --- a/drivers/usb/dwc3/core.h
>>> +++ b/drivers/usb/dwc3/core.h
>>> @@ -734,6 +734,9 @@ struct dwc3_scratchpad_array {
>>>   *   1       - -3.5dB de-emphasis
>>>   *   2       - No de-emphasis
>>>   *   3       - Reserved
>>> + * @can_save_power: set if the gadget will power off when no cable plug in.
>>
>> nope
>>
>>> + * @need_restart: set if we need to restart the gadget.
>>
>> why does it need restart? Why is dwc3 powered off? Who powers it off?
>
> Because when the dwc3 Vbus is off (no cable pluging in now),
> especially for some mobile device, the system need to power off the
> dwc3 to save power in this situation.

but dwc3 doesn't do this by itself, so who's doing it?

>> This looks like a *really* bad power management implementation. Do you
>> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
>> version are you using? How was it configured?
>
> This is not hibernation, we want to power off the dwc3 to save power
> when no cable plugging in. Yes, we have clock gating, at this
> situation we will disable the clock and shutdown the phy to save
> power. For mobile device, most time no cable plugging in, so we need
> to think about the power consuming. How do you think this requirement?

Well, seems like you're missing *proper* runtime PM. I've been meaning
to work on it for weeks, but I still have a few other things to do
before I get to that. In any case, we don't need to do what you did
here. There are better ways.

>> Anyway, which platform are you dealing with? Why is dwc3 off while VBUS
>> is off? How do you handle host mode?
>
> On Spreadtrum platform, for thinking about some mobile devices with

I meant the SoC ;-) It's their own SoC? Are we getting glue-layer
patches any time soon?

> strict power management. This is just for gadget mode, we don't power
> off the dwc3 when it is host mode. Thanks.

okay, thanks

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-13 12:09     ` Felipe Balbi
@ 2016-05-13 12:35       ` Baolin Wang
  2016-05-13 12:46         ` Felipe Balbi
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-13 12:35 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

On 13 May 2016 at 20:09, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>>>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>>>> index 6254b2f..dada5c6 100644
>>>> --- a/drivers/usb/dwc3/core.h
>>>> +++ b/drivers/usb/dwc3/core.h
>>>> @@ -734,6 +734,9 @@ struct dwc3_scratchpad_array {
>>>>   *   1       - -3.5dB de-emphasis
>>>>   *   2       - No de-emphasis
>>>>   *   3       - Reserved
>>>> + * @can_save_power: set if the gadget will power off when no cable plug in.
>>>
>>> nope
>>>
>>>> + * @need_restart: set if we need to restart the gadget.
>>>
>>> why does it need restart? Why is dwc3 powered off? Who powers it off?
>>
>> Because when the dwc3 Vbus is off (no cable pluging in now),
>> especially for some mobile device, the system need to power off the
>> dwc3 to save power in this situation.
>
> but dwc3 doesn't do this by itself, so who's doing it?

Yes, the dwc3 clock is controlled by the Soc system, so the Soc system
can disable the dwc3 clock when there is no cable plugging in.

>
>>> This looks like a *really* bad power management implementation. Do you
>>> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
>>> version are you using? How was it configured?
>>
>> This is not hibernation, we want to power off the dwc3 to save power
>> when no cable plugging in. Yes, we have clock gating, at this
>> situation we will disable the clock and shutdown the phy to save
>> power. For mobile device, most time no cable plugging in, so we need
>> to think about the power consuming. How do you think this requirement?
>
> Well, seems like you're missing *proper* runtime PM. I've been meaning
> to work on it for weeks, but I still have a few other things to do
> before I get to that. In any case, we don't need to do what you did
> here. There are better ways.

Make sense.

>
>>> Anyway, which platform are you dealing with? Why is dwc3 off while VBUS
>>> is off? How do you handle host mode?
>>
>> On Spreadtrum platform, for thinking about some mobile devices with
>
> I meant the SoC ;-) It's their own SoC? Are we getting glue-layer
> patches any time soon?

Yes, it's their own SoC. Thanks.

>
>> strict power management. This is just for gadget mode, we don't power
>> off the dwc3 when it is host mode. Thanks.
>
> okay, thanks
>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-13 12:35       ` Baolin Wang
@ 2016-05-13 12:46         ` Felipe Balbi
  2016-05-15  5:24           ` Baolin Wang
  2016-05-17  7:56           ` Baolin Wang
  0 siblings, 2 replies; 19+ messages in thread
From: Felipe Balbi @ 2016-05-13 12:46 UTC (permalink / raw)
  To: Baolin Wang; +Cc: Greg KH, Mark Brown, USB, LKML

[-- Attachment #1: Type: text/plain, Size: 1499 bytes --]


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
>>>> why does it need restart? Why is dwc3 powered off? Who powers it off?
>>>
>>> Because when the dwc3 Vbus is off (no cable pluging in now),
>>> especially for some mobile device, the system need to power off the
>>> dwc3 to save power in this situation.
>>
>> but dwc3 doesn't do this by itself, so who's doing it?
>
> Yes, the dwc3 clock is controlled by the Soc system, so the Soc system
> can disable the dwc3 clock when there is no cable plugging in.

understood.

>>>> This looks like a *really* bad power management implementation. Do you
>>>> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
>>>> version are you using? How was it configured?
>>>
>>> This is not hibernation, we want to power off the dwc3 to save power
>>> when no cable plugging in. Yes, we have clock gating, at this
>>> situation we will disable the clock and shutdown the phy to save
>>> power. For mobile device, most time no cable plugging in, so we need
>>> to think about the power consuming. How do you think this requirement?
>>
>> Well, seems like you're missing *proper* runtime PM. I've been meaning
>> to work on it for weeks, but I still have a few other things to do
>> before I get to that. In any case, we don't need to do what you did
>> here. There are better ways.
>
> Make sense.

cool, if you wanna work on it, let me know and I can give some details
of what I have in mind.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-13 12:46         ` Felipe Balbi
@ 2016-05-15  5:24           ` Baolin Wang
  2016-05-17  7:56           ` Baolin Wang
  1 sibling, 0 replies; 19+ messages in thread
From: Baolin Wang @ 2016-05-15  5:24 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

On 13 May 2016 at 20:46, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>> why does it need restart? Why is dwc3 powered off? Who powers it off?
>>>>
>>>> Because when the dwc3 Vbus is off (no cable pluging in now),
>>>> especially for some mobile device, the system need to power off the
>>>> dwc3 to save power in this situation.
>>>
>>> but dwc3 doesn't do this by itself, so who's doing it?
>>
>> Yes, the dwc3 clock is controlled by the Soc system, so the Soc system
>> can disable the dwc3 clock when there is no cable plugging in.
>
> understood.
>
>>>>> This looks like a *really* bad power management implementation. Do you
>>>>> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
>>>>> version are you using? How was it configured?
>>>>
>>>> This is not hibernation, we want to power off the dwc3 to save power
>>>> when no cable plugging in. Yes, we have clock gating, at this
>>>> situation we will disable the clock and shutdown the phy to save
>>>> power. For mobile device, most time no cable plugging in, so we need
>>>> to think about the power consuming. How do you think this requirement?
>>>
>>> Well, seems like you're missing *proper* runtime PM. I've been meaning
>>> to work on it for weeks, but I still have a few other things to do
>>> before I get to that. In any case, we don't need to do what you did
>>> here. There are better ways.
>>
>> Make sense.
>
> cool, if you wanna work on it, let me know and I can give some details
> of what I have in mind.

OK. I would like to do that, please help to give me some details. Thanks.

>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-13 12:46         ` Felipe Balbi
  2016-05-15  5:24           ` Baolin Wang
@ 2016-05-17  7:56           ` Baolin Wang
  2016-05-17  8:00             ` Felipe Balbi
  1 sibling, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-17  7:56 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

Hi Felipe,

On 13 May 2016 at 20:46, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>> why does it need restart? Why is dwc3 powered off? Who powers it off?
>>>>
>>>> Because when the dwc3 Vbus is off (no cable pluging in now),
>>>> especially for some mobile device, the system need to power off the
>>>> dwc3 to save power in this situation.
>>>
>>> but dwc3 doesn't do this by itself, so who's doing it?
>>
>> Yes, the dwc3 clock is controlled by the Soc system, so the Soc system
>> can disable the dwc3 clock when there is no cable plugging in.
>
> understood.
>
>>>>> This looks like a *really* bad power management implementation. Do you
>>>>> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
>>>>> version are you using? How was it configured?
>>>>
>>>> This is not hibernation, we want to power off the dwc3 to save power
>>>> when no cable plugging in. Yes, we have clock gating, at this
>>>> situation we will disable the clock and shutdown the phy to save
>>>> power. For mobile device, most time no cable plugging in, so we need
>>>> to think about the power consuming. How do you think this requirement?
>>>
>>> Well, seems like you're missing *proper* runtime PM. I've been meaning
>>> to work on it for weeks, but I still have a few other things to do
>>> before I get to that. In any case, we don't need to do what you did
>>> here. There are better ways.
>>
>> Make sense.
>
> cool, if you wanna work on it, let me know and I can give some details
> of what I have in mind.

Could you explain details to me, and I wanna continue to optimize the
power management things. Thanks.

>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-17  7:56           ` Baolin Wang
@ 2016-05-17  8:00             ` Felipe Balbi
  2016-05-17  8:45               ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2016-05-17  8:00 UTC (permalink / raw)
  To: Baolin Wang; +Cc: Greg KH, Mark Brown, USB, LKML

[-- Attachment #1: Type: text/plain, Size: 2187 bytes --]


Hi

Baolin Wang <baolin.wang@linaro.org> writes:
> Hi Felipe,
>
> On 13 May 2016 at 20:46, Felipe Balbi <balbi@kernel.org> wrote:
>>
>> Hi,
>>
>> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>>> why does it need restart? Why is dwc3 powered off? Who powers it off?
>>>>>
>>>>> Because when the dwc3 Vbus is off (no cable pluging in now),
>>>>> especially for some mobile device, the system need to power off the
>>>>> dwc3 to save power in this situation.
>>>>
>>>> but dwc3 doesn't do this by itself, so who's doing it?
>>>
>>> Yes, the dwc3 clock is controlled by the Soc system, so the Soc system
>>> can disable the dwc3 clock when there is no cable plugging in.
>>
>> understood.
>>
>>>>>> This looks like a *really* bad power management implementation. Do you
>>>>>> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
>>>>>> version are you using? How was it configured?
>>>>>
>>>>> This is not hibernation, we want to power off the dwc3 to save power
>>>>> when no cable plugging in. Yes, we have clock gating, at this
>>>>> situation we will disable the clock and shutdown the phy to save
>>>>> power. For mobile device, most time no cable plugging in, so we need
>>>>> to think about the power consuming. How do you think this requirement?
>>>>
>>>> Well, seems like you're missing *proper* runtime PM. I've been meaning
>>>> to work on it for weeks, but I still have a few other things to do
>>>> before I get to that. In any case, we don't need to do what you did
>>>> here. There are better ways.
>>>
>>> Make sense.
>>
>> cool, if you wanna work on it, let me know and I can give some details
>> of what I have in mind.
>
> Could you explain details to me, and I wanna continue to optimize the
> power management things. Thanks.

I have it half-way done. Have a look at my dwc3-fix-suspend branch on
k.org. I haven't sent because I'm not getting a PME event. Can you test
on your end and let me know what happens?

Note that if cable is disconnected, we will drop RUN/STOP bit. On
runtime_resume, we will restart the controller from scratch (skipping
memory allocations, of course)

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-17  8:00             ` Felipe Balbi
@ 2016-05-17  8:45               ` Baolin Wang
  2016-05-17  9:25                 ` Felipe Balbi
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-17  8:45 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

On 17 May 2016 at 16:00, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>> Hi Felipe,
>>
>> On 13 May 2016 at 20:46, Felipe Balbi <balbi@kernel.org> wrote:
>>>
>>> Hi,
>>>
>>> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>>>> why does it need restart? Why is dwc3 powered off? Who powers it off?
>>>>>>
>>>>>> Because when the dwc3 Vbus is off (no cable pluging in now),
>>>>>> especially for some mobile device, the system need to power off the
>>>>>> dwc3 to save power in this situation.
>>>>>
>>>>> but dwc3 doesn't do this by itself, so who's doing it?
>>>>
>>>> Yes, the dwc3 clock is controlled by the Soc system, so the Soc system
>>>> can disable the dwc3 clock when there is no cable plugging in.
>>>
>>> understood.
>>>
>>>>>>> This looks like a *really* bad power management implementation. Do you
>>>>>>> have hibernation enabled? Do you have Clock gating enabled? Which dwc3
>>>>>>> version are you using? How was it configured?
>>>>>>
>>>>>> This is not hibernation, we want to power off the dwc3 to save power
>>>>>> when no cable plugging in. Yes, we have clock gating, at this
>>>>>> situation we will disable the clock and shutdown the phy to save
>>>>>> power. For mobile device, most time no cable plugging in, so we need
>>>>>> to think about the power consuming. How do you think this requirement?
>>>>>
>>>>> Well, seems like you're missing *proper* runtime PM. I've been meaning
>>>>> to work on it for weeks, but I still have a few other things to do
>>>>> before I get to that. In any case, we don't need to do what you did
>>>>> here. There are better ways.
>>>>
>>>> Make sense.
>>>
>>> cool, if you wanna work on it, let me know and I can give some details
>>> of what I have in mind.
>>
>> Could you explain details to me, and I wanna continue to optimize the
>> power management things. Thanks.
>
> I have it half-way done. Have a look at my dwc3-fix-suspend branch on
> k.org. I haven't sent because I'm not getting a PME event. Can you test
> on your end and let me know what happens?

OK. I try to test on my platform to see what will happen.

>
> Note that if cable is disconnected, we will drop RUN/STOP bit. On
> runtime_resume, we will restart the controller from scratch (skipping
> memory allocations, of course)
>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-17  8:45               ` Baolin Wang
@ 2016-05-17  9:25                 ` Felipe Balbi
  2016-05-17 10:47                   ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2016-05-17  9:25 UTC (permalink / raw)
  To: Baolin Wang; +Cc: Greg KH, Mark Brown, USB, LKML

[-- Attachment #1: Type: text/plain, Size: 680 bytes --]


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
>>>>> Make sense.
>>>>
>>>> cool, if you wanna work on it, let me know and I can give some details
>>>> of what I have in mind.
>>>
>>> Could you explain details to me, and I wanna continue to optimize the
>>> power management things. Thanks.
>>
>> I have it half-way done. Have a look at my dwc3-fix-suspend branch on
>> k.org. I haven't sent because I'm not getting a PME event. Can you test
>> on your end and let me know what happens?
>
> OK. I try to test on my platform to see what will happen.

great, thanks. You might need to patch your glue layer with proper
runtime_* callbacks, btw.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-17  9:25                 ` Felipe Balbi
@ 2016-05-17 10:47                   ` Baolin Wang
  2016-05-18  9:59                     ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-17 10:47 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

On 17 May 2016 at 17:25, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>>> Make sense.
>>>>>
>>>>> cool, if you wanna work on it, let me know and I can give some details
>>>>> of what I have in mind.
>>>>
>>>> Could you explain details to me, and I wanna continue to optimize the
>>>> power management things. Thanks.
>>>
>>> I have it half-way done. Have a look at my dwc3-fix-suspend branch on
>>> k.org. I haven't sent because I'm not getting a PME event. Can you test
>>> on your end and let me know what happens?
>>
>> OK. I try to test on my platform to see what will happen.
>
> great, thanks. You might need to patch your glue layer with proper
> runtime_* callbacks, btw.

Make sense. Thanks.

>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-17 10:47                   ` Baolin Wang
@ 2016-05-18  9:59                     ` Baolin Wang
  2016-05-18 10:12                       ` Felipe Balbi
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-18  9:59 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

Hi Felipe,

On 17 May 2016 at 18:47, Baolin Wang <baolin.wang@linaro.org> wrote:
> On 17 May 2016 at 17:25, Felipe Balbi <balbi@kernel.org> wrote:
>>
>> Hi,
>>
>> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>>>> Make sense.
>>>>>>
>>>>>> cool, if you wanna work on it, let me know and I can give some details
>>>>>> of what I have in mind.
>>>>>
>>>>> Could you explain details to me, and I wanna continue to optimize the
>>>>> power management things. Thanks.
>>>>
>>>> I have it half-way done. Have a look at my dwc3-fix-suspend branch on
>>>> k.org. I haven't sent because I'm not getting a PME event. Can you test
>>>> on your end and let me know what happens?

I applied some patches (showing below) about suspend/resume at your
dwc3-fix-suspend branch with my glue layer runtime_* callbacks on my
testing platform.
usb: dwc3: implement runtime PM
usb: dwc3: core: simplify suspend/resume operations
usb: dwc3: core: re-factor init and exit paths
usb: dwc3: core: get rid of DWC3_PM_OPS macro
usb: dwc3: gadget: fix gadget suspend/resume
usb: dwc3: gadget: re-factor ->udc_start and ->udc_stop

Then I tested the cable connect/disconnect action to see the dwc core
resume/suspend. It looks work well on my platform, except that I did
some extra 2 modifications like below:
(1)
@@ -1485,16 +1490,11 @@ static int dwc3_gadget_run_stop(struct dwc3
*dwc, int is_on, int suspend)
 {
        u32                     reg;
        u32                     timeout = 500, i;

+       if (pm_runtime_suspended(dwc->dev))
+               return 0;

(2)
@@ -1748,15 +1754,25 @@ static int dwc3_gadget_start(struct usb_gadget *g,
         * even though host mode might be active. Don't actually perform
         * device-specific initialization until device mode is activated.
         */

+       if (pm_runtime_suspended(dwc->dev)) {
+               spin_unlock_irqrestore(&dwc->lock, flags);
+               return 0;
+       }

+       ret = __dwc3_gadget_start(dwc);
+       if (ret)
+               goto err1;

So I think the dwc3 core can enter suspend mode before gadget function
is ready to call the 'usb_gadget_udc_start()' and
'usb_udc_connect_control()', then if the dwc3 core has entered
suspended mode, we need to return success when starting the gadget,
and leave the gadget starting action from gadget resume. What do you
think about that? Thanks.

>>>
>>> OK. I try to test on my platform to see what will happen.
>>
>> great, thanks. You might need to patch your glue layer with proper
>> runtime_* callbacks, btw.
>
> Make sense. Thanks.
>
>>
>> --
>> balbi
>
>
>
> --
> Baolin.wang
> Best Regards



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-18  9:59                     ` Baolin Wang
@ 2016-05-18 10:12                       ` Felipe Balbi
  2016-05-18 10:17                         ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2016-05-18 10:12 UTC (permalink / raw)
  To: Baolin Wang; +Cc: Greg KH, Mark Brown, USB, LKML

[-- Attachment #1: Type: text/plain, Size: 2588 bytes --]


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
>>> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>>>>> Make sense.
>>>>>>>
>>>>>>> cool, if you wanna work on it, let me know and I can give some details
>>>>>>> of what I have in mind.
>>>>>>
>>>>>> Could you explain details to me, and I wanna continue to optimize the
>>>>>> power management things. Thanks.
>>>>>
>>>>> I have it half-way done. Have a look at my dwc3-fix-suspend branch on
>>>>> k.org. I haven't sent because I'm not getting a PME event. Can you test
>>>>> on your end and let me know what happens?
>
> I applied some patches (showing below) about suspend/resume at your
> dwc3-fix-suspend branch with my glue layer runtime_* callbacks on my
> testing platform.
> usb: dwc3: implement runtime PM
> usb: dwc3: core: simplify suspend/resume operations
> usb: dwc3: core: re-factor init and exit paths
> usb: dwc3: core: get rid of DWC3_PM_OPS macro
> usb: dwc3: gadget: fix gadget suspend/resume
> usb: dwc3: gadget: re-factor ->udc_start and ->udc_stop
>
> Then I tested the cable connect/disconnect action to see the dwc core
> resume/suspend. It looks work well on my platform, except that I did
> some extra 2 modifications like below:
> (1)
> @@ -1485,16 +1490,11 @@ static int dwc3_gadget_run_stop(struct dwc3
> *dwc, int is_on, int suspend)
>  {
>         u32                     reg;
>         u32                     timeout = 500, i;
>
> +       if (pm_runtime_suspended(dwc->dev))
> +               return 0;
>
> (2)
> @@ -1748,15 +1754,25 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>          * even though host mode might be active. Don't actually perform
>          * device-specific initialization until device mode is activated.
>          */
>
> +       if (pm_runtime_suspended(dwc->dev)) {
> +               spin_unlock_irqrestore(&dwc->lock, flags);
> +               return 0;
> +       }
>
> +       ret = __dwc3_gadget_start(dwc);
> +       if (ret)
> +               goto err1;
>
> So I think the dwc3 core can enter suspend mode before gadget function
> is ready to call the 'usb_gadget_udc_start()' and
> 'usb_udc_connect_control()', then if the dwc3 core has entered
> suspended mode, we need to return success when starting the gadget,
> and leave the gadget starting action from gadget resume. What do you
> think about that? Thanks.

Well, if this makes it work properly. Then, yeah; looks okay to me. I'll
add this to the patch introducing runtime PM.

Thanks a lot for testing on your side :-)

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-18 10:12                       ` Felipe Balbi
@ 2016-05-18 10:17                         ` Baolin Wang
  2016-05-18 10:22                           ` Felipe Balbi
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-18 10:17 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

On 18 May 2016 at 18:12, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>>>> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>>>>>> Make sense.
>>>>>>>>
>>>>>>>> cool, if you wanna work on it, let me know and I can give some details
>>>>>>>> of what I have in mind.
>>>>>>>
>>>>>>> Could you explain details to me, and I wanna continue to optimize the
>>>>>>> power management things. Thanks.
>>>>>>
>>>>>> I have it half-way done. Have a look at my dwc3-fix-suspend branch on
>>>>>> k.org. I haven't sent because I'm not getting a PME event. Can you test
>>>>>> on your end and let me know what happens?
>>
>> I applied some patches (showing below) about suspend/resume at your
>> dwc3-fix-suspend branch with my glue layer runtime_* callbacks on my
>> testing platform.
>> usb: dwc3: implement runtime PM
>> usb: dwc3: core: simplify suspend/resume operations
>> usb: dwc3: core: re-factor init and exit paths
>> usb: dwc3: core: get rid of DWC3_PM_OPS macro
>> usb: dwc3: gadget: fix gadget suspend/resume
>> usb: dwc3: gadget: re-factor ->udc_start and ->udc_stop
>>
>> Then I tested the cable connect/disconnect action to see the dwc core
>> resume/suspend. It looks work well on my platform, except that I did
>> some extra 2 modifications like below:
>> (1)
>> @@ -1485,16 +1490,11 @@ static int dwc3_gadget_run_stop(struct dwc3
>> *dwc, int is_on, int suspend)
>>  {
>>         u32                     reg;
>>         u32                     timeout = 500, i;
>>
>> +       if (pm_runtime_suspended(dwc->dev))
>> +               return 0;
>>
>> (2)
>> @@ -1748,15 +1754,25 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>>          * even though host mode might be active. Don't actually perform
>>          * device-specific initialization until device mode is activated.
>>          */
>>
>> +       if (pm_runtime_suspended(dwc->dev)) {
>> +               spin_unlock_irqrestore(&dwc->lock, flags);
>> +               return 0;
>> +       }
>>
>> +       ret = __dwc3_gadget_start(dwc);
>> +       if (ret)
>> +               goto err1;
>>
>> So I think the dwc3 core can enter suspend mode before gadget function
>> is ready to call the 'usb_gadget_udc_start()' and
>> 'usb_udc_connect_control()', then if the dwc3 core has entered
>> suspended mode, we need to return success when starting the gadget,
>> and leave the gadget starting action from gadget resume. What do you
>> think about that? Thanks.
>
> Well, if this makes it work properly. Then, yeah; looks okay to me. I'll
> add this to the patch introducing runtime PM.

OK.

>
> Thanks a lot for testing on your side :-)

You are welcome:)

>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-18 10:17                         ` Baolin Wang
@ 2016-05-18 10:22                           ` Felipe Balbi
  2016-05-18 11:06                             ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2016-05-18 10:22 UTC (permalink / raw)
  To: Baolin Wang; +Cc: Greg KH, Mark Brown, USB, LKML

[-- Attachment #1: Type: text/plain, Size: 1890 bytes --]


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
>>> @@ -1485,16 +1490,11 @@ static int dwc3_gadget_run_stop(struct dwc3
>>> *dwc, int is_on, int suspend)
>>>  {
>>>         u32                     reg;
>>>         u32                     timeout = 500, i;
>>>
>>> +       if (pm_runtime_suspended(dwc->dev))
>>> +               return 0;
>>>
>>> (2)
>>> @@ -1748,15 +1754,25 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>>>          * even though host mode might be active. Don't actually perform
>>>          * device-specific initialization until device mode is activated.
>>>          */
>>>
>>> +       if (pm_runtime_suspended(dwc->dev)) {
>>> +               spin_unlock_irqrestore(&dwc->lock, flags);
>>> +               return 0;
>>> +       }
>>>
>>> +       ret = __dwc3_gadget_start(dwc);
>>> +       if (ret)
>>> +               goto err1;
>>>
>>> So I think the dwc3 core can enter suspend mode before gadget function
>>> is ready to call the 'usb_gadget_udc_start()' and
>>> 'usb_udc_connect_control()', then if the dwc3 core has entered
>>> suspended mode, we need to return success when starting the gadget,
>>> and leave the gadget starting action from gadget resume. What do you
>>> think about that? Thanks.
>>
>> Well, if this makes it work properly. Then, yeah; looks okay to me. I'll
>> add this to the patch introducing runtime PM.
>
> OK.

I've updated the branch with slightly modified version of your
changes. Can you test again just to make sure it still works ?

Basically, here's what I did:

on dwc3_gadget_start:

-       __dwc3_gadget_start(dwc);
+       if (pm_runtime_active(dwc->dev))
+               __dwc3_gadget_start(dwc);
+

on run_stop, I kept the same thing.

you just need to replace "usb: dwc3: implement runtime PM" with the new
version from my branch.

cheers

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-18 10:22                           ` Felipe Balbi
@ 2016-05-18 11:06                             ` Baolin Wang
  2016-05-18 11:21                               ` Felipe Balbi
  0 siblings, 1 reply; 19+ messages in thread
From: Baolin Wang @ 2016-05-18 11:06 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

Hi,

On 18 May 2016 at 18:22, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>>>> @@ -1485,16 +1490,11 @@ static int dwc3_gadget_run_stop(struct dwc3
>>>> *dwc, int is_on, int suspend)
>>>>  {
>>>>         u32                     reg;
>>>>         u32                     timeout = 500, i;
>>>>
>>>> +       if (pm_runtime_suspended(dwc->dev))
>>>> +               return 0;
>>>>
>>>> (2)
>>>> @@ -1748,15 +1754,25 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>>>>          * even though host mode might be active. Don't actually perform
>>>>          * device-specific initialization until device mode is activated.
>>>>          */
>>>>
>>>> +       if (pm_runtime_suspended(dwc->dev)) {
>>>> +               spin_unlock_irqrestore(&dwc->lock, flags);
>>>> +               return 0;
>>>> +       }
>>>>
>>>> +       ret = __dwc3_gadget_start(dwc);
>>>> +       if (ret)
>>>> +               goto err1;
>>>>
>>>> So I think the dwc3 core can enter suspend mode before gadget function
>>>> is ready to call the 'usb_gadget_udc_start()' and
>>>> 'usb_udc_connect_control()', then if the dwc3 core has entered
>>>> suspended mode, we need to return success when starting the gadget,
>>>> and leave the gadget starting action from gadget resume. What do you
>>>> think about that? Thanks.
>>>
>>> Well, if this makes it work properly. Then, yeah; looks okay to me. I'll
>>> add this to the patch introducing runtime PM.
>>
>> OK.
>
> I've updated the branch with slightly modified version of your
> changes. Can you test again just to make sure it still works ?
>
> Basically, here's what I did:
>
> on dwc3_gadget_start:
>
> -       __dwc3_gadget_start(dwc);
> +       if (pm_runtime_active(dwc->dev))
> +               __dwc3_gadget_start(dwc);
> +

Great.

>
> on run_stop, I kept the same thing.
>
> you just need to replace "usb: dwc3: implement runtime PM" with the new
> version from my branch.

Yeah, it can work well on my platform with your new patch.

>
> cheers
>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-18 11:06                             ` Baolin Wang
@ 2016-05-18 11:21                               ` Felipe Balbi
  2016-05-18 11:26                                 ` Baolin Wang
  0 siblings, 1 reply; 19+ messages in thread
From: Felipe Balbi @ 2016-05-18 11:21 UTC (permalink / raw)
  To: Baolin Wang; +Cc: Greg KH, Mark Brown, USB, LKML

[-- Attachment #1: Type: text/plain, Size: 1885 bytes --]


Hi,

Baolin Wang <baolin.wang@linaro.org> writes:
>>>>> @@ -1748,15 +1754,25 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>>>>>          * even though host mode might be active. Don't actually perform
>>>>>          * device-specific initialization until device mode is activated.
>>>>>          */
>>>>>
>>>>> +       if (pm_runtime_suspended(dwc->dev)) {
>>>>> +               spin_unlock_irqrestore(&dwc->lock, flags);
>>>>> +               return 0;
>>>>> +       }
>>>>>
>>>>> +       ret = __dwc3_gadget_start(dwc);
>>>>> +       if (ret)
>>>>> +               goto err1;
>>>>>
>>>>> So I think the dwc3 core can enter suspend mode before gadget function
>>>>> is ready to call the 'usb_gadget_udc_start()' and
>>>>> 'usb_udc_connect_control()', then if the dwc3 core has entered
>>>>> suspended mode, we need to return success when starting the gadget,
>>>>> and leave the gadget starting action from gadget resume. What do you
>>>>> think about that? Thanks.
>>>>
>>>> Well, if this makes it work properly. Then, yeah; looks okay to me. I'll
>>>> add this to the patch introducing runtime PM.
>>>
>>> OK.
>>
>> I've updated the branch with slightly modified version of your
>> changes. Can you test again just to make sure it still works ?
>>
>> Basically, here's what I did:
>>
>> on dwc3_gadget_start:
>>
>> -       __dwc3_gadget_start(dwc);
>> +       if (pm_runtime_active(dwc->dev))
>> +               __dwc3_gadget_start(dwc);
>> +
>
> Great.
>
>>
>> on run_stop, I kept the same thing.
>>
>> you just need to replace "usb: dwc3: implement runtime PM" with the new
>> version from my branch.
>
> Yeah, it can work well on my platform with your new patch.

cool, thanks again :-) I'll drop my "not for merging note" and add your
"Tested-by" (assuming it's okay for you that I do it).

cheers

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on
  2016-05-18 11:21                               ` Felipe Balbi
@ 2016-05-18 11:26                                 ` Baolin Wang
  0 siblings, 0 replies; 19+ messages in thread
From: Baolin Wang @ 2016-05-18 11:26 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Greg KH, Mark Brown, USB, LKML

On 18 May 2016 at 19:21, Felipe Balbi <balbi@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.wang@linaro.org> writes:
>>>>>> @@ -1748,15 +1754,25 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>>>>>>          * even though host mode might be active. Don't actually perform
>>>>>>          * device-specific initialization until device mode is activated.
>>>>>>          */
>>>>>>
>>>>>> +       if (pm_runtime_suspended(dwc->dev)) {
>>>>>> +               spin_unlock_irqrestore(&dwc->lock, flags);
>>>>>> +               return 0;
>>>>>> +       }
>>>>>>
>>>>>> +       ret = __dwc3_gadget_start(dwc);
>>>>>> +       if (ret)
>>>>>> +               goto err1;
>>>>>>
>>>>>> So I think the dwc3 core can enter suspend mode before gadget function
>>>>>> is ready to call the 'usb_gadget_udc_start()' and
>>>>>> 'usb_udc_connect_control()', then if the dwc3 core has entered
>>>>>> suspended mode, we need to return success when starting the gadget,
>>>>>> and leave the gadget starting action from gadget resume. What do you
>>>>>> think about that? Thanks.
>>>>>
>>>>> Well, if this makes it work properly. Then, yeah; looks okay to me. I'll
>>>>> add this to the patch introducing runtime PM.
>>>>
>>>> OK.
>>>
>>> I've updated the branch with slightly modified version of your
>>> changes. Can you test again just to make sure it still works ?
>>>
>>> Basically, here's what I did:
>>>
>>> on dwc3_gadget_start:
>>>
>>> -       __dwc3_gadget_start(dwc);
>>> +       if (pm_runtime_active(dwc->dev))
>>> +               __dwc3_gadget_start(dwc);
>>> +
>>
>> Great.
>>
>>>
>>> on run_stop, I kept the same thing.
>>>
>>> you just need to replace "usb: dwc3: implement runtime PM" with the new
>>> version from my branch.
>>
>> Yeah, it can work well on my platform with your new patch.
>
> cool, thanks again :-) I'll drop my "not for merging note" and add your
> "Tested-by" (assuming it's okay for you that I do it).

It's okay for me. Thanks.

>
> cheers
>
> --
> balbi



-- 
Baolin.wang
Best Regards

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-05-18 11:26 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-13 10:24 [PATCH] dwc3: gadget: Defer starting the gadget device until gadget is power on Baolin Wang
2016-05-13 10:40 ` Felipe Balbi
2016-05-13 11:34   ` Baolin Wang
2016-05-13 12:09     ` Felipe Balbi
2016-05-13 12:35       ` Baolin Wang
2016-05-13 12:46         ` Felipe Balbi
2016-05-15  5:24           ` Baolin Wang
2016-05-17  7:56           ` Baolin Wang
2016-05-17  8:00             ` Felipe Balbi
2016-05-17  8:45               ` Baolin Wang
2016-05-17  9:25                 ` Felipe Balbi
2016-05-17 10:47                   ` Baolin Wang
2016-05-18  9:59                     ` Baolin Wang
2016-05-18 10:12                       ` Felipe Balbi
2016-05-18 10:17                         ` Baolin Wang
2016-05-18 10:22                           ` Felipe Balbi
2016-05-18 11:06                             ` Baolin Wang
2016-05-18 11:21                               ` Felipe Balbi
2016-05-18 11:26                                 ` Baolin Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).