public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] usb: dwc3: Properly set system wakeup
@ 2024-03-08  2:40 Thinh Nguyen
  2024-03-08  7:01 ` Sanath S
  2024-03-08 14:34 ` Guilherme G. Piccoli
  0 siblings, 2 replies; 4+ messages in thread
From: Thinh Nguyen @ 2024-03-08  2:40 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Thinh Nguyen, linux-usb@vger.kernel.org
  Cc: John Youn, Guilherme G.Piccoli, stable@vger.kernel.org

If the device is configured for system wakeup, then make sure that the
xHCI driver knows about it and make sure to permit wakeup only at the
appropriate time.

For host mode, if the controller goes through the dwc3 code path, then a
child xHCI platform device is created. Make sure the platform device
also inherits the wakeup setting for xHCI to enable remote wakeup.

For device mode, make sure to disable system wakeup if no gadget driver
is bound. We may experience unwanted system wakeup due to the wakeup
signal from the controller PMU detecting connection/disconnection when
in low power (D3). E.g. In the case of Steam Deck, the PCI PME prevents
the system staying in suspend.

Cc: stable@vger.kernel.org
Reported-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
Closes: https://lore.kernel.org/linux-usb/70a7692d-647c-9be7-00a6-06fc60f77294@igalia.com/T/#mf00d6669c2eff7b308d1162acd1d66c09f0853c7
Fixes: d07e8819a03d ("usb: dwc3: add xHCI Host support")
Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
---
 drivers/usb/dwc3/core.c   |  2 ++
 drivers/usb/dwc3/core.h   |  2 ++
 drivers/usb/dwc3/gadget.c | 10 ++++++++++
 drivers/usb/dwc3/host.c   | 11 +++++++++++
 4 files changed, 25 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 3e55838c0001..31684cdaaae3 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1519,6 +1519,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 	else
 		dwc->sysdev = dwc->dev;
 
+	dwc->sys_wakeup = device_may_wakeup(dwc->sysdev);
+
 	ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name);
 	if (ret >= 0) {
 		dwc->usb_psy = power_supply_get_by_name(usb_psy_name);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index e120611a5174..893b1e694efe 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1132,6 +1132,7 @@ struct dwc3_scratchpad_array {
  *	3	- Reserved
  * @dis_metastability_quirk: set to disable metastability quirk.
  * @dis_split_quirk: set to disable split boundary.
+ * @sys_wakeup: set if the device may do system wakeup.
  * @wakeup_configured: set if the device is configured for remote wakeup.
  * @suspended: set to track suspend event due to U3/L2.
  * @imod_interval: set the interrupt moderation interval in 250ns
@@ -1355,6 +1356,7 @@ struct dwc3 {
 
 	unsigned		dis_split_quirk:1;
 	unsigned		async_callbacks:1;
+	unsigned		sys_wakeup:1;
 	unsigned		wakeup_configured:1;
 	unsigned		suspended:1;
 
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 28f49400f3e8..07820b1a88a2 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2968,6 +2968,9 @@ static int dwc3_gadget_start(struct usb_gadget *g,
 	dwc->gadget_driver	= driver;
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
+	if (dwc->sys_wakeup)
+		device_wakeup_enable(dwc->sysdev);
+
 	return 0;
 }
 
@@ -2983,6 +2986,9 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 	struct dwc3		*dwc = gadget_to_dwc(g);
 	unsigned long		flags;
 
+	if (dwc->sys_wakeup)
+		device_wakeup_disable(dwc->sysdev);
+
 	spin_lock_irqsave(&dwc->lock, flags);
 	dwc->gadget_driver	= NULL;
 	dwc->max_cfg_eps = 0;
@@ -4664,6 +4670,10 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 	else
 		dwc3_gadget_set_speed(dwc->gadget, dwc->maximum_speed);
 
+	/* No system wakeup if no gadget driver bound */
+	if (dwc->sys_wakeup)
+		device_wakeup_disable(dwc->sysdev);
+
 	return 0;
 
 err5:
diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
index 43230915323c..f6a020d77fa1 100644
--- a/drivers/usb/dwc3/host.c
+++ b/drivers/usb/dwc3/host.c
@@ -123,6 +123,14 @@ int dwc3_host_init(struct dwc3 *dwc)
 		goto err;
 	}
 
+	if (dwc->sys_wakeup) {
+		/* Restore wakeup setting if switched from device */
+		device_wakeup_enable(dwc->sysdev);
+
+		/* Pass on wakeup setting to the new xhci platform device */
+		device_init_wakeup(&xhci->dev, true);
+	}
+
 	return 0;
 err:
 	platform_device_put(xhci);
@@ -131,6 +139,9 @@ int dwc3_host_init(struct dwc3 *dwc)
 
 void dwc3_host_exit(struct dwc3 *dwc)
 {
+	if (dwc->sys_wakeup)
+		device_init_wakeup(&dwc->xhci->dev, false);
+
 	platform_device_unregister(dwc->xhci);
 	dwc->xhci = NULL;
 }

base-commit: b234c70fefa7532d34ebee104de64cc16f1b21e4
-- 
2.28.0

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

* Re: [PATCH] usb: dwc3: Properly set system wakeup
  2024-03-08  2:40 [PATCH] usb: dwc3: Properly set system wakeup Thinh Nguyen
@ 2024-03-08  7:01 ` Sanath S
  2024-03-08 14:34 ` Guilherme G. Piccoli
  1 sibling, 0 replies; 4+ messages in thread
From: Sanath S @ 2024-03-08  7:01 UTC (permalink / raw)
  To: Thinh Nguyen, Greg Kroah-Hartman, linux-usb@vger.kernel.org
  Cc: John Youn, Guilherme G.Piccoli, stable@vger.kernel.org


On 3/8/2024 8:10 AM, Thinh Nguyen wrote:
> If the device is configured for system wakeup, then make sure that the
> xHCI driver knows about it and make sure to permit wakeup only at the
> appropriate time.
>
> For host mode, if the controller goes through the dwc3 code path, then a
> child xHCI platform device is created. Make sure the platform device
> also inherits the wakeup setting for xHCI to enable remote wakeup.
>
> For device mode, make sure to disable system wakeup if no gadget driver
> is bound. We may experience unwanted system wakeup due to the wakeup
> signal from the controller PMU detecting connection/disconnection when
> in low power (D3). E.g. In the case of Steam Deck, the PCI PME prevents
> the system staying in suspend.
We were chasing down same issue at our end and found this patch to be 
helpful.
Tested on both host and device mode. Patch is working as expected.

Please feel free to add my tag
Tested-by: Sanath S <Sanath.S@amd.com>
> Cc: stable@vger.kernel.org
> Reported-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
> Closes: https://lore.kernel.org/linux-usb/70a7692d-647c-9be7-00a6-06fc60f77294@igalia.com/T/#mf00d6669c2eff7b308d1162acd1d66c09f0853c7
> Fixes: d07e8819a03d ("usb: dwc3: add xHCI Host support")
> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
> ---
>   drivers/usb/dwc3/core.c   |  2 ++
>   drivers/usb/dwc3/core.h   |  2 ++
>   drivers/usb/dwc3/gadget.c | 10 ++++++++++
>   drivers/usb/dwc3/host.c   | 11 +++++++++++
>   4 files changed, 25 insertions(+)
>
> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> index 3e55838c0001..31684cdaaae3 100644
> --- a/drivers/usb/dwc3/core.c
> +++ b/drivers/usb/dwc3/core.c
> @@ -1519,6 +1519,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
>   	else
>   		dwc->sysdev = dwc->dev;
>   
> +	dwc->sys_wakeup = device_may_wakeup(dwc->sysdev);
> +
>   	ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name);
>   	if (ret >= 0) {
>   		dwc->usb_psy = power_supply_get_by_name(usb_psy_name);
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index e120611a5174..893b1e694efe 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -1132,6 +1132,7 @@ struct dwc3_scratchpad_array {
>    *	3	- Reserved
>    * @dis_metastability_quirk: set to disable metastability quirk.
>    * @dis_split_quirk: set to disable split boundary.
> + * @sys_wakeup: set if the device may do system wakeup.
>    * @wakeup_configured: set if the device is configured for remote wakeup.
>    * @suspended: set to track suspend event due to U3/L2.
>    * @imod_interval: set the interrupt moderation interval in 250ns
> @@ -1355,6 +1356,7 @@ struct dwc3 {
>   
>   	unsigned		dis_split_quirk:1;
>   	unsigned		async_callbacks:1;
> +	unsigned		sys_wakeup:1;
>   	unsigned		wakeup_configured:1;
>   	unsigned		suspended:1;
>   
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 28f49400f3e8..07820b1a88a2 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -2968,6 +2968,9 @@ static int dwc3_gadget_start(struct usb_gadget *g,
>   	dwc->gadget_driver	= driver;
>   	spin_unlock_irqrestore(&dwc->lock, flags);
>   
> +	if (dwc->sys_wakeup)
> +		device_wakeup_enable(dwc->sysdev);
> +
>   	return 0;
>   }
>   
> @@ -2983,6 +2986,9 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
>   	struct dwc3		*dwc = gadget_to_dwc(g);
>   	unsigned long		flags;
>   
> +	if (dwc->sys_wakeup)
> +		device_wakeup_disable(dwc->sysdev);
> +
>   	spin_lock_irqsave(&dwc->lock, flags);
>   	dwc->gadget_driver	= NULL;
>   	dwc->max_cfg_eps = 0;
> @@ -4664,6 +4670,10 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>   	else
>   		dwc3_gadget_set_speed(dwc->gadget, dwc->maximum_speed);
>   
> +	/* No system wakeup if no gadget driver bound */
> +	if (dwc->sys_wakeup)
> +		device_wakeup_disable(dwc->sysdev);
> +
>   	return 0;
>   
>   err5:
> diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
> index 43230915323c..f6a020d77fa1 100644
> --- a/drivers/usb/dwc3/host.c
> +++ b/drivers/usb/dwc3/host.c
> @@ -123,6 +123,14 @@ int dwc3_host_init(struct dwc3 *dwc)
>   		goto err;
>   	}
>   
> +	if (dwc->sys_wakeup) {
> +		/* Restore wakeup setting if switched from device */
> +		device_wakeup_enable(dwc->sysdev);
> +
> +		/* Pass on wakeup setting to the new xhci platform device */
> +		device_init_wakeup(&xhci->dev, true);
> +	}
> +
>   	return 0;
>   err:
>   	platform_device_put(xhci);
> @@ -131,6 +139,9 @@ int dwc3_host_init(struct dwc3 *dwc)
>   
>   void dwc3_host_exit(struct dwc3 *dwc)
>   {
> +	if (dwc->sys_wakeup)
> +		device_init_wakeup(&dwc->xhci->dev, false);
> +
>   	platform_device_unregister(dwc->xhci);
>   	dwc->xhci = NULL;
>   }
>
> base-commit: b234c70fefa7532d34ebee104de64cc16f1b21e4

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

* Re: [PATCH] usb: dwc3: Properly set system wakeup
  2024-03-08  2:40 [PATCH] usb: dwc3: Properly set system wakeup Thinh Nguyen
  2024-03-08  7:01 ` Sanath S
@ 2024-03-08 14:34 ` Guilherme G. Piccoli
  2024-03-15  1:03   ` Thinh Nguyen
  1 sibling, 1 reply; 4+ messages in thread
From: Guilherme G. Piccoli @ 2024-03-08 14:34 UTC (permalink / raw)
  To: Thinh Nguyen
  Cc: John Youn, stable@vger.kernel.org, John Schoenick, Andrey Smirnov,
	Vivek Dasmohapatra, Greg Kroah-Hartman, linux-usb@vger.kernel.org

On 07/03/2024 23:40, Thinh Nguyen wrote:
> If the device is configured for system wakeup, then make sure that the
> xHCI driver knows about it and make sure to permit wakeup only at the
> appropriate time.
> 
> For host mode, if the controller goes through the dwc3 code path, then a
> child xHCI platform device is created. Make sure the platform device
> also inherits the wakeup setting for xHCI to enable remote wakeup.
> 
> For device mode, make sure to disable system wakeup if no gadget driver
> is bound. We may experience unwanted system wakeup due to the wakeup
> signal from the controller PMU detecting connection/disconnection when
> in low power (D3). E.g. In the case of Steam Deck, the PCI PME prevents
> the system staying in suspend.
> 
> Cc: stable@vger.kernel.org
> Reported-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
> Closes: https://lore.kernel.org/linux-usb/70a7692d-647c-9be7-00a6-06fc60f77294@igalia.com/T/#mf00d6669c2eff7b308d1162acd1d66c09f0853c7
> Fixes: d07e8819a03d ("usb: dwc3: add xHCI Host support")
> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>

[CCing some interested parties here from Deck development teams]

Hi Thinh, thanks a bunch for the fix, and all the support and attention
on this issue - much appreciated!

I've tested this fix on top of v6.8-rc7, in the Steam Deck, and it
manages to resolve the sleep problems we have on device mode.
So, feel free to add:

Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com> # Steam Deck


Should we try to get it included last minute on v6.8, or better to make
use of the merge window opening next week?
Cheers,


Guilherme

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

* Re: [PATCH] usb: dwc3: Properly set system wakeup
  2024-03-08 14:34 ` Guilherme G. Piccoli
@ 2024-03-15  1:03   ` Thinh Nguyen
  0 siblings, 0 replies; 4+ messages in thread
From: Thinh Nguyen @ 2024-03-15  1:03 UTC (permalink / raw)
  To: Guilherme G. Piccoli
  Cc: Thinh Nguyen, John Youn, stable@vger.kernel.org, John Schoenick,
	Andrey Smirnov, Vivek Dasmohapatra, Greg Kroah-Hartman,
	linux-usb@vger.kernel.org

On Fri, Mar 08, 2024, Guilherme G. Piccoli wrote:
> On 07/03/2024 23:40, Thinh Nguyen wrote:
> > If the device is configured for system wakeup, then make sure that the
> > xHCI driver knows about it and make sure to permit wakeup only at the
> > appropriate time.
> > 
> > For host mode, if the controller goes through the dwc3 code path, then a
> > child xHCI platform device is created. Make sure the platform device
> > also inherits the wakeup setting for xHCI to enable remote wakeup.
> > 
> > For device mode, make sure to disable system wakeup if no gadget driver
> > is bound. We may experience unwanted system wakeup due to the wakeup
> > signal from the controller PMU detecting connection/disconnection when
> > in low power (D3). E.g. In the case of Steam Deck, the PCI PME prevents
> > the system staying in suspend.
> > 
> > Cc: stable@vger.kernel.org
> > Reported-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
> > Closes: https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/70a7692d-647c-9be7-00a6-06fc60f77294@igalia.com/T/*mf00d6669c2eff7b308d1162acd1d66c09f0853c7__;Iw!!A4F2R9G_pg!ZfwA13IkDcmBYR7ixglzsLs4-QWUsNErsqd3dI-BzTBRhoJJBb506OjCpVl0frTP--uYJsuwQx-ztB0m2UQKYg$ 
> > Fixes: d07e8819a03d ("usb: dwc3: add xHCI Host support")
> > Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
> 
> [CCing some interested parties here from Deck development teams]
> 
> Hi Thinh, thanks a bunch for the fix, and all the support and attention
> on this issue - much appreciated!
> 
> I've tested this fix on top of v6.8-rc7, in the Steam Deck, and it
> manages to resolve the sleep problems we have on device mode.
> So, feel free to add:
> 
> Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com> # Steam Deck
> 
> 
> Should we try to get it included last minute on v6.8, or better to make
> use of the merge window opening next week?
> Cheers,
> 

It's up to Greg. But at this point, I think we'll probably need to wait
until after v6.9-rc1.

BR,
Thinh

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

end of thread, other threads:[~2024-03-15  1:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-08  2:40 [PATCH] usb: dwc3: Properly set system wakeup Thinh Nguyen
2024-03-08  7:01 ` Sanath S
2024-03-08 14:34 ` Guilherme G. Piccoli
2024-03-15  1:03   ` Thinh Nguyen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox