Skip to contentSkip to conversation

Allow DWC3 runtime suspend if UDC is unbinded

PATCH Superseded Wesley Cheng 1 participant 3 messages Nov 5, 2020

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 5d879b7606d5..babf977cadc0 100644
@@ -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
#2 lore raw

PATCH v2 2/2 usb: dwc3: gadget: Preserve UDC max speed setting

In reply to Wesley Cheng

The 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
index 2f04b3e42bf1..390d3deef0ba 100644
@@ -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