return DWC3_DSTS_USBLNKST(reg);
}
+static bool dwc3_gadget_is_suspended(struct dwc3 *dwc)
+{
+ enum dwc3_link_state link_state;
+
+ if (atomic_read(&dwc->in_lpm)) {
+ return true;
+ } else {
+ link_state = dwc3_get_link_state(dwc);
+ if (link_state == DWC3_LINK_STATE_RX_DET ||
+ link_state == DWC3_LINK_STATE_U3)
+ return true;
+ }
+
+ return false;
+}
+
static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
gfp_t gfp_flags)
{
goto out;
}
+ if (dwc3_gadget_is_suspended(dwc)) {
+ if (dwc->gadget.remote_wakeup)
+ dwc3_gadget_wakeup(&dwc->gadget);
+ ret = dwc->gadget.remote_wakeup ? -EAGAIN : -ENOTSUPP;
+ goto out;
+ }
+
ret = __dwc3_gadget_ep_queue(dep, req);
out:
if (!g || (g->speed != USB_SPEED_SUPER))
return -ENOTSUPP;
+ if (dwc3_gadget_is_suspended(dwc)) {
+ pr_debug("USB bus is suspended. Scheduling wakeup and returning -EAGAIN.\n");
+ dwc3_gadget_wakeup(&dwc->gadget);
+ return -EAGAIN;
+ }
+
ret = dwc3_send_gadget_generic_command(dwc,
DWC3_DGCMD_XMIT_FUNCTION, interface_id);