Hi, On Mon, Mar 04, 2024, Guilherme G. Piccoli wrote: > On 08/02/2024 22:18, Guilherme G. Piccoli wrote: > > On 08/02/2024 20:53, Thinh Nguyen wrote: > >> [...] > >> > >> Thanks. I have some suspicions of what happened. I'll create a patch, > >> but I'll need some time. > >> > >> Thanks, > >> Thinh > > > > Thank you a bunch! Let us know when you have a candidate, I can test it > > quickly in the Steam Deck =) > > > > Cheers, > > > > > > Guilherme > > > > Hi Thinh, hope everything is alright. > > Let me know if we can help in anything or provide more test results, > we'd be glad to. > Can you try this? I made some adjustments to the previous conditions: * If operate as device mode, only allow system wakeup if there's gadget * driver binded. * Make sure to pass the wakeup config to the xhci platform device when switch to host. If it works, I'll clean this up and split this into 2 separate patches. Thanks, Thinh diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 3e55838c0001..63202b1748d3 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1977,6 +1977,8 @@ static int dwc3_probe(struct platform_device *pdev) pm_runtime_forbid(dev); + dwc->sys_wakeup = !!device_may_wakeup(dwc->sysdev); + ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index c07edfc954f7..7e80dd3d466b 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1133,6 +1133,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 @@ -1357,6 +1358,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 40c52dbc28d3..2d394c4ad735 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2955,6 +2955,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; } @@ -2970,6 +2973,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; @@ -4651,6 +4657,9 @@ int dwc3_gadget_init(struct dwc3 *dwc) else dwc3_gadget_set_speed(dwc->gadget, dwc->maximum_speed); + 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 5a5cb6ce9946..8a72d4005352 100644 --- a/drivers/usb/dwc3/host.c +++ b/drivers/usb/dwc3/host.c @@ -173,6 +173,14 @@ int dwc3_host_init(struct dwc3 *dwc) goto err; } + if (dwc->sys_wakeup) { + /* Restore/re-enable wakeup if switched from device */ + device_wakeup_enable(dwc->sysdev); + + /* Pass wakeup config to the new xhci platform device */ + device_init_wakeup(&xhci->dev, true); + } + return 0; err: platform_device_put(xhci); diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 3d071b875308..abbf4d751a54 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -451,6 +451,9 @@ static int xhci_plat_suspend(struct device *dev) ret = xhci_priv_suspend_quirk(hcd); if (ret) return ret; + + dev_info(dev, "%s: device_may_wakeup: %d\n", + __func__, !!device_may_wakeup(dev)); /* * xhci_suspend() needs `do_wakeup` to know whether host is allowed * to do wakeup during suspend.