summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>2019-12-19 05:14:44 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-01-15 12:39:23 +0300
commitc58d8bfc77a2c7f6ff6339b58c9fca7ae6f57e70 (patch)
tree2768ffe8860e0ee2e6d17694262838611ebc9a1a /drivers/usb/dwc3/gadget.c
parent6b02af3465ee11b63a938b13bddbf7ecd92860f3 (diff)
downloadlinux-c58d8bfc77a2c7f6ff6339b58c9fca7ae6f57e70.tar.xz
usb: dwc3: gadget: Check END_TRANSFER completion
While the END_TRANSFER command is sent but not completed, any request dequeue during this time will cause the driver to issue the END_TRANSFER command. The driver needs to submit the command only once to stop the controller from processing further. The controller may take more time to process the same command multiple times unnecessarily. Let's add a flag DWC3_EP_END_TRANSFER_PENDING to check for this condition. Fixes: 3aec99154db3 ("usb: dwc3: gadget: remove DWC3_EP_END_TRANSFER_PENDING") Signed-off-by: Thinh Nguyen <thinhn@synopsys.com> Signed-off-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index edc478c20846..cf163dcc5524 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2628,6 +2628,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
cmd = DEPEVT_PARAMETER_CMD(event->parameters);
if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
+ dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
dwc3_gadget_ep_cleanup_cancelled_requests(dep);
}
@@ -2686,7 +2687,8 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
u32 cmd;
int ret;
- if (!(dep->flags & DWC3_EP_TRANSFER_STARTED))
+ if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
+ (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
return;
/*
@@ -2731,6 +2733,8 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
if (!interrupt)
dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+ else
+ dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A)
udelay(100);