diff options
author | Felipe Balbi <balbi@ti.com> | 2011-10-14 15:11:49 +0300 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2011-12-12 11:48:42 +0200 |
commit | df62df56e13d73cb0dd4c54649d4fe13557128f8 (patch) | |
tree | 1436686e851eb583433c98963496e53be1d3420b /drivers/usb/dwc3/gadget.c | |
parent | 05870c5ba2002c7d49adf8875cca49ee062af894 (diff) | |
download | lwn-df62df56e13d73cb0dd4c54649d4fe13557128f8.tar.gz lwn-df62df56e13d73cb0dd4c54649d4fe13557128f8.zip |
usb: dwc3: workaround: missing disconnect event
DWC3 revisions <1.88a have an issue which would
case a missing Disconnect event if cable is
disconnected while there's a Setup packet
pending the FIFO.
Signed-off-by: Felipe Balbi <balbi@ti.com>
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 6704a52c9f12..7c98b3f2e6a7 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); |