diff options
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 6704a52..7c98b3f 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1640,6 +1640,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) dwc->start_config_issued = false; dwc->gadget.speed = USB_SPEED_UNKNOWN; + dwc->setup_packet_pending = false; } static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on) @@ -1676,6 +1677,37 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dev_vdbg(dwc->dev, "%s\n", __func__); + /* + * WORKAROUND: DWC3 revisions <1.88a have an issue which + * would cause a missing Disconnect Event if there's a + * pending Setup Packet in the FIFO. + * + * There's no suggested workaround on the official Bug + * report, which states that "unless the driver/application + * is doing any special handling of a disconnect event, + * there is no functional issue". + * + * Unfortunately, it turns out that we _do_ some special + * handling of a disconnect event, namely complete all + * pending transfers, notify gadget driver of the + * disconnection, and so on. + * + * Our suggested workaround is to follow the Disconnect + * Event steps here, instead, based on a setup_packet_pending + * flag. Such flag gets set whenever we have a XferNotReady + * event on EP0 and gets cleared on XferComplete for the + * same endpoint. + * + * Refers to: + * + * STAR#9000466709: RTL: Device : Disconnect event not + * generated if setup packet pending in FIFO + */ + if (dwc->revision < DWC3_REVISION_188A) { + if (dwc->setup_packet_pending) + dwc3_gadget_disconnect_interrupt(dwc); + } + /* Enable PHYs */ dwc3_gadget_usb2_phy_power(dwc, true); dwc3_gadget_usb3_phy_power(dwc, true); |