summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2022-12-06 11:13:26 +0100
committerTakashi Iwai <tiwai@suse.de>2022-12-06 11:13:26 +0100
commit8ec2d95f50c06f5cf2a2b94bcdf47f494f91ad55 (patch)
tree2d6c60670a5a1575780b080e00ca2b26d62f5403 /drivers/usb/dwc3/gadget.c
parentcf2ea3c86ad90d63d1c572b43e1ca9276b0357ad (diff)
parent9472382db38452df15f9f2f74b1dff34848e56b2 (diff)
downloadlinux-stable-8ec2d95f50c06f5cf2a2b94bcdf47f494f91ad55.tar.gz
linux-stable-8ec2d95f50c06f5cf2a2b94bcdf47f494f91ad55.tar.bz2
linux-stable-8ec2d95f50c06f5cf2a2b94bcdf47f494f91ad55.zip
Merge tag 'asoc-v6.2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v6.2 This is a fairly sedate release for the core code, but there's been a lot of driver work especially around the x86 platforms and device tree updates: - More cleanups of the DAPM code from Morimoto-san. - Factoring out of mapping hw_params onto SoundWire configuration by Charles Keepax. - The ever ongoing overhauls of the Intel DSP code continue, including support for loading libraries and probes with IPC4 on SOF. - Support for more sample formats on JZ4740. - Lots of device tree conversions and fixups. - Support for Allwinner D1, a range of AMD and Intel systems, Mediatek systems with multiple DMICs, Nuvoton NAU8318, NXP fsl_rpmsg and i.MX93, Qualcomm AudioReach Enable, MFC and SAL, RealTek RT1318 and Rockchip RK3588 There's more cross tree updates than usual, though all fairly minor: - Some OMAP board file updates that were depedencies for removing their providers in ASoC, as part of a wider effort removing the support for the relevant OMAP platforms. - A new I2C API required for updates to the new I2C probe API. - A DRM update making use of a new API for fixing the capabilities advertised via hdmi-codec. Since this is being sent early I might send some more stuff if you've not yet sent your pull request and there's more come in.
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 079cd333632e..026d4029bda6 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1029,7 +1029,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
dep->endpoint.desc = NULL;
}
- dwc3_remove_requests(dwc, dep, -ECONNRESET);
+ dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
dep->stream_capable = false;
dep->type = 0;
@@ -1292,8 +1292,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
}
- /* always enable Interrupt on Missed ISOC */
- trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
+ if (!no_interrupt && !chain)
+ trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
break;
case USB_ENDPOINT_XFER_BULK:
@@ -1698,6 +1698,16 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
memset(&params, 0, sizeof(params));
ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
+ /*
+ * If the End Transfer command was timed out while the device is
+ * not in SETUP phase, it's possible that an incoming Setup packet
+ * may prevent the command's completion. Let's retry when the
+ * ep0state returns to EP0_SETUP_PHASE.
+ */
+ if (ret == -ETIMEDOUT && dep->dwc->ep0state != EP0_SETUP_PHASE) {
+ dep->flags |= DWC3_EP_DELAY_STOP;
+ return 0;
+ }
WARN_ON_ONCE(ret);
dep->resource_index = 0;
@@ -3238,6 +3248,10 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
if (event->status & DEPEVT_STATUS_SHORT && !chain)
return 1;
+ if ((trb->ctrl & DWC3_TRB_CTRL_ISP_IMI) &&
+ DWC3_TRB_SIZE_TRBSTS(trb->size) == DWC3_TRBSTS_MISSED_ISOC)
+ return 1;
+
if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
(trb->ctrl & DWC3_TRB_CTRL_LST))
return 1;
@@ -3719,7 +3733,7 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
* timeout. Delay issuing the End Transfer command until the Setup TRB is
* prepared.
*/
- if (dwc->ep0state != EP0_SETUP_PHASE) {
+ if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status) {
dep->flags |= DWC3_EP_DELAY_STOP;
return;
}