Allow DWC3 runtime suspend if UDC is unbinded
Subsystems (2)
v2 cover Allow DWC3 runtime suspend if UDC is unbinded
Changes in v2:
- Modified logic for executing the runtime PM resume. Using a sychronous get call to avoid race conditions.
During the following scenario, the DWC3 runtime suspend routine is blocked as the connected flag is still true:
1. Enumerate device w/ host.
2. Gadget is unbinded
- echo "" > /sys/kernel/config/usb_gadget/g1/UDC
3. Disconnect the USB cable (VBUS low)
4. No dwc3_gadget_disconnect_interrupt() seen (since controller is halted from step#1)
5. Runtime PM autosuspend fails due to "dwc->connected" being true (cleared in dwc3_gadget_disconnect_interrupt())
6. Gadget binded
- echo udc_name > /sys/kernel/config/usb_gadget/g1/UDC
7. No runtime suspend until cable is plugged in and out
Technically, for device initiated disconnects, there is no active session/link with the host, so the DWC3 controller should be allowed to go into a low power state. Also, we need to now consider when re-binding the UDC, dwc3_gadget_set_speed() is executed before dwc3_gadget_pullup(), so if the DWC3 controller is suspended/disabled, while accessing the DCFG, that could result in bus timeouts, etc... Change the dwc3_gadget_set_speed() to save the speed being requested, and program it during dwc3_gadget_run_stop(), which is executed during PM runtime resume. If not, previous setting will be overridden as we execute a DWC3 controller reset during PM runtime resume.
Wesley Cheng (2):
usb: dwc3: gadget: Allow runtime suspend if UDC unbinded
usb: dwc3: gadget: Preserve UDC max speed setting
drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 121 ++++++++++++++++++++++---------------- 2 files changed, 71 insertions(+), 51 deletions(-)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v2 1/2 usb: dwc3: gadget: Allow runtime suspend if UDC unbinded
The DWC3 runtime suspend routine checks for the USB connected parameter to determine if the controller can enter into a low power state. The connected state is only set to false after receiving a disconnect event. However, in the case of a device initiated disconnect (i.e. UDC unbind), the controller is halted and a disconnect event is never generated. Set the connected flag to false if issuing a device initiated disconnect to allow the controller to be suspended.
--- drivers/usb/dwc3/gadget.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/usb/dwc3/gadget.c +13 -0
@@ -2012,6 +2012,17 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) } } +/* +* Check the return value for successful resume, or error. For a +* successful resume, the DWC3 runtime PM resume routine will handle +* the run stop sequence, so avoid duplicate operations here. +*/ + ret =pm_runtime_get_sync (dwc->dev); +if (!ret || ret <0 ) { +pm_runtime_put (dwc->dev); +return 0 ; + } +/* * Synchronize any pending event handling before executing the controller * halt routine.
@@ -2050,10 +2061,12 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % dwc->ev_buf->length; } + dwc->connected = false; } ret =dwc3_gadget_run_stop (dwc, is_on, false);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put (dwc->dev);return ret; }
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v2 2/2 usb: dwc3: gadget: Preserve UDC max speed setting
In reply to Wesley ChengThe USB gadget/UDC driver can restrict the DWC3 controller speed using dwc3_gadget_set_speed(). Store this setting into a variable, in order for this setting to persist across controller resets due to runtime PM.
--- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 108 ++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 51 deletions(-)
drivers/usb/dwc3/core.h +1 -0
@@ -1119,6 +1119,7 @@ struct dwc3 {u32 nr_scratch;u32 u1u2;u32 maximum_speed; +u32 gadget_max_speed;u32 ip;
drivers/usb/dwc3/gadget.c +57 -51
128 lines not on this page · raw message
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project