diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index e5998bab73f5..ea2abd3e8a19 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -778,6 +778,7 @@ struct dwc3_ep { unsigned direction:1; unsigned stream_capable:1; unsigned gsi:1; + unsigned int endless:1; /* For isochronous START TRANSFER workaround only */ u8 combo_num; diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 61df412f75eb..9db35699f77a 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -2060,6 +2060,15 @@ int msm_ep_unconfig(struct usb_ep *ep) return 0; } EXPORT_SYMBOL(msm_ep_unconfig); + +void msm_ep_set_endless(struct usb_ep *ep, bool set_clear) +{ + struct dwc3_ep *dep = to_dwc3_ep(ep); + + dep->endless = !!set_clear; +} +EXPORT_SYMBOL(msm_ep_set_endless); + #endif /* (CONFIG_USB_DWC3_GADGET) || (CONFIG_USB_DWC3_DUAL_ROLE) */ static void dwc3_resume_work(struct work_struct *w); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1bedfb92fd0d..36a80b4a2da8 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -778,8 +778,8 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) * Issue StartTransfer here with no-op TRB so we can always rely on No * Response Update Transfer command. */ - if ((usb_endpoint_xfer_bulk(desc) && !dep->stream_capable) || - usb_endpoint_xfer_int(desc)) { + if ((usb_endpoint_xfer_bulk(desc) && !dep->stream_capable + && !dep->endless) || usb_endpoint_xfer_int(desc)) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; dma_addr_t trb_dma; diff --git a/drivers/usb/gadget/function/f_qdss.c b/drivers/usb/gadget/function/f_qdss.c index e70a859a866b..7b244c374bbf 100644 --- a/drivers/usb/gadget/function/f_qdss.c +++ b/drivers/usb/gadget/function/f_qdss.c @@ -2,7 +2,7 @@ /* * f_qdss.c -- QDSS function Driver * - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -11,6 +11,7 @@ #include #include #include +#include #include "f_qdss.h" @@ -374,8 +375,10 @@ static void clear_eps(struct usb_function *f) qdss->port.ctrl_in->driver_data = NULL; if (qdss->port.ctrl_out) qdss->port.ctrl_out->driver_data = NULL; - if (qdss->port.data) + if (qdss->port.data) { + msm_ep_set_endless(qdss->port.data, false); qdss->port.data->driver_data = NULL; + } } static void clear_desc(struct usb_gadget *gadget, struct usb_function *f) @@ -443,6 +446,9 @@ static int qdss_bind(struct usb_configuration *c, struct usb_function *f) qdss->port.data = ep; ep->driver_data = qdss; + if (!strcmp(qdss->ch.name, USB_QDSS_CH_MSM)) + msm_ep_set_endless(qdss->port.data, true); + if (qdss->debug_inface_enabled) { ep = usb_ep_autoconfig_ss(gadget, &qdss_ss_ctrl_in_desc, &qdss_ctrl_in_ep_comp_desc); diff --git a/include/linux/usb/dwc3-msm.h b/include/linux/usb/dwc3-msm.h index 38a2fd2541ee..b978cdbed655 100644 --- a/include/linux/usb/dwc3-msm.h +++ b/include/linux/usb/dwc3-msm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #ifndef __LINUX_USB_DWC3_MSM_H @@ -115,6 +115,7 @@ struct usb_ep *usb_ep_autoconfig_by_name(struct usb_gadget *gadget, int usb_gsi_ep_op(struct usb_ep *ep, void *op_data, enum gsi_ep_op op); int msm_ep_config(struct usb_ep *ep, struct usb_request *request, u32 bam_opts); int msm_ep_unconfig(struct usb_ep *ep); +void msm_ep_set_endless(struct usb_ep *ep, bool set_clear); void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable); int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr, u32 size, u8 dst_pipe_idx); @@ -136,6 +137,8 @@ static inline int msm_ep_config(struct usb_ep *ep, struct usb_request *request, { return -ENODEV; } static inline int msm_ep_unconfig(struct usb_ep *ep) { return -ENODEV; } +static inline void msm_ep_set_endless(struct usb_ep *ep, bool set_clear) +{ } static inline void dwc3_tx_fifo_resize_request(struct usb_ep *ep, bool qdss_enable) { }