From c3a06d3145ad50abfd11b627fbacf9cafda3425e Mon Sep 17 00:00:00 2001 From: William Wu Date: Mon, 14 Sep 2020 11:39:12 +0800 Subject: [PATCH] usb: dwc3: gadget: avoid repeatedly resizing txfifos The current code resize the txfifos for all assigned endpoints when enable ep. If we config the USB function as UVC, the txfifos will be resized every time when we open UVC. It's safely to resize the txfifos if only UVC is used. However, if we config the USB as a composite device (UVC + RNDIS), and if we resize the txfifos when the RNDIS data transfer in progress, it may make the controller broken. To fix this issue, we only resize the txfifos the first time we enable the isoc eps. Change-Id: I6b4fa093bff1a9752fbbd7bd4401b998ff02ad23 Signed-off-by: William Wu --- drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/gadget.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 2f4d79d53a33..5b362eda94b1 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1042,6 +1042,7 @@ struct dwc3_scratchpad_array { * 3 - Reserved * @dis_metastability_quirk: set to disable metastability quirk. * @needs_fifo_resize: set if we want to resize TXFIFO. + * @fifo_resize_status: true if the TXFIFOs have been resized. * @drd_connected: true when usb connected to a host or a device(drd mode), * false otherwise. * @en_runtime: true when need runtime PM management. For example, RK3399 need @@ -1237,6 +1238,7 @@ struct dwc3 { unsigned dis_metastability_quirk:1; unsigned needs_fifo_resize:1; + unsigned fifo_resize_status:1; unsigned drd_connected:1; unsigned en_runtime:1; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 1f7be980e44b..a58e776145b9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -164,7 +164,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) int mdwidth; u8 num, fifo_number; - if (!dwc->needs_fifo_resize) + if (!dwc->needs_fifo_resize || dwc->fifo_resize_status) return 0; mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); @@ -223,6 +223,8 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) fifo_number++; } + dwc->fifo_resize_status = true; + return 0; } @@ -890,7 +892,8 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep, ret = __dwc3_gadget_ep_enable(dep, DWC3_DEPCFG_ACTION_INIT); spin_unlock_irqrestore(&dwc->lock, flags); - dwc3_gadget_resize_tx_fifos(dwc); + if (usb_endpoint_xfer_isoc(ep->desc)) + dwc3_gadget_resize_tx_fifos(dwc); return ret; } @@ -2192,6 +2195,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g) __dwc3_gadget_stop(dwc); out1: + dwc->fifo_resize_status = false; dwc->gadget_driver = NULL; spin_unlock_irqrestore(&dwc->lock, flags);