diff options
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f20975300594..8f8c2157910e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2695,6 +2695,17 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, dwc->link_state = next; } +static void dwc3_gadget_suspend_interrupt(struct dwc3 *dwc, + unsigned int evtinfo) +{ + enum dwc3_link_state next = evtinfo & DWC3_LINK_STATE_MASK; + + if (dwc->link_state != next && next == DWC3_LINK_STATE_U3) + dwc3_suspend_gadget(dwc); + + dwc->link_state = next; +} + static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc, unsigned int evtinfo) { @@ -2746,7 +2757,20 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, dwc3_gadget_linksts_change_interrupt(dwc, event->event_info); break; case DWC3_DEVICE_EVENT_EOPF: - dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame"); + /* It changed to be suspend event for version 2.30a and above */ + if (dwc->revision < DWC3_REVISION_230A) { + dwc3_trace(trace_dwc3_gadget, "End of Periodic Frame"); + } else { + dwc3_trace(trace_dwc3_gadget, "U3/L1-L2 Suspend Event"); + + /* + * Ignore suspend event until the gadget enters into + * USB_STATE_CONFIGURED state. + */ + if (dwc->gadget.state >= USB_STATE_CONFIGURED) + dwc3_gadget_suspend_interrupt(dwc, + event->event_info); + } break; case DWC3_DEVICE_EVENT_SOF: dwc3_trace(trace_dwc3_gadget, "Start of Periodic Frame"); |