Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e537ca8 authored by Mayank Rana's avatar Mayank Rana
Browse files

dwc3: Add USB function suspend/resume related handling



Currently dwc3 driver doesn't hand over USB function suspend/resume
request to composite layer as those are supposed to be handle by
USB function driver. This change adds support for it. It also adds
function remote wakeup functionality which is needed by USB function
suspended interface to perform remote wakeup towards USB host for
resume interface related functionality.

Change-Id: I1f9ecc60346e16fad87439cc12c551e05b4f3491
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent bf131dca
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@
static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
		struct dwc3_ep *dep, struct dwc3_request *req);
static int dwc3_ep0_delegate_req(struct dwc3 *dwc,
		struct usb_ctrlrequest *ctrl);

static void dwc3_ep0_prepare_one_trb(struct dwc3_ep *dep,
		dma_addr_t buf_dma, u32 len, u32 type, bool chain)
@@ -352,7 +354,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
		 * Function Remote Wake Capable	D0
		 * Function Remote Wakeup	D1
		 */
		break;
		return dwc3_ep0_delegate_req(dwc, ctrl);

	case USB_RECIP_ENDPOINT:
		dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
@@ -507,6 +509,9 @@ static int dwc3_ep0_handle_intf(struct dwc3 *dwc,
		 * For now, we're not doing anything, just making sure we return
		 * 0 so USB Command Verifier tests pass without any errors.
		 */
		ret = dwc3_ep0_delegate_req(dwc, ctrl);
		if (ret)
			return ret;
		break;
	default:
		ret = -EINVAL;
+25 −0
Original line number Diff line number Diff line
@@ -2116,6 +2116,28 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
	return 0;
}

#ifdef CONFIG_USB_FUNC_WAKEUP_SUPPORTED
static int dwc_gadget_func_wakeup(struct usb_gadget *g, int interface_id)
{
	int ret = 0;
	struct dwc3 *dwc = gadget_to_dwc(g);

	if (dwc3_gadget_is_suspended(dwc)) {
		dev_dbg(dwc->dev, "USB bus is suspended, scheduling wakeup\n");
		dwc3_gadget_wakeup(&dwc->gadget);
		return -EAGAIN;
	}

	ret = dwc3_send_gadget_generic_command(dwc, DWC3_DGCMD_XMIT_DEV,
			0x1 | (interface_id << 4));
	if (ret)
		dev_err(dwc->dev, "Function wakeup HW command failed, ret %d\n",
				ret);

	return ret;
}
#endif

static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
		int is_selfpowered)
{
@@ -2770,6 +2792,9 @@ static void __maybe_unused dwc3_gadget_set_speed(struct usb_gadget *g,
static const struct usb_gadget_ops dwc3_gadget_ops = {
	.get_frame		= dwc3_gadget_get_frame,
	.wakeup			= dwc3_gadget_wakeup,
#ifdef CONFIG_USB_FUNC_WAKEUP_SUPPORTED
	.func_wakeup		= dwc_gadget_func_wakeup,
#endif
	.set_selfpowered	= dwc3_gadget_set_selfpowered,
	.vbus_session		= dwc3_gadget_vbus_session,
	.vbus_draw		= dwc3_gadget_vbus_draw,