summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorThinh Nguyen <Thinh.Nguyen@synopsys.com>2020-10-01 02:44:25 +0200
committerFelipe Balbi <balbi@kernel.org>2020-10-02 08:57:46 +0200
commit8dbbe48c7a9989c75e39bfb2a886e163fa21660a (patch)
tree25923f5d3040fba4e7f42c38191a2c6f9cf122ff /drivers/usb/dwc3
parentusb: dwc3: gadget: Look ahead when setting IOC (diff)
downloadlinux-8dbbe48c7a9989c75e39bfb2a886e163fa21660a.tar.xz
linux-8dbbe48c7a9989c75e39bfb2a886e163fa21660a.zip
usb: dwc3: gadget: Revise setting IOC when no TRB left
To keep the setting of interrupt-on-completion (IOC) when out of TRBs consistent and easier to read, the caller of dwc3_prepare_one_trb() will determine if the TRB must have IOC bit set. This also reduces the number of times we need to call dwc3_calc_trbs_left(). Note that we only care about setting IOC from insufficient number of TRBs for SG and not linear requests (because we don't need to split linear requests). Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/gadget.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 0387b94b8f94..327cd556e8db 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1034,8 +1034,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
}
- if ((!no_interrupt && !chain) || must_interrupt ||
- (dwc3_calc_trbs_left(dep) == 1))
+ if ((!no_interrupt && !chain) || must_interrupt)
trb->ctrl |= DWC3_TRB_CTRL_IOC;
if (chain)
@@ -1169,6 +1168,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
length -= sg_dma_len(s);
for_each_sg(sg, s, remaining, i) {
+ unsigned int num_trbs_left = dwc3_calc_trbs_left(dep);
unsigned int trb_length;
bool must_interrupt = false;
bool last_sg = false;
@@ -1187,7 +1187,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
if ((i == remaining - 1) || !length)
last_sg = true;
- if (!dwc3_calc_trbs_left(dep))
+ if (!num_trbs_left)
break;
if (last_sg) {
@@ -1196,12 +1196,13 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
} else {
/*
* Look ahead to check if we have enough TRBs for the
- * last SG entry. If not, set interrupt on this TRB to
- * resume preparing the last SG entry when more TRBs are
+ * next SG entry. If not, set interrupt on this TRB to
+ * resume preparing the next SG entry when more TRBs are
* free.
*/
- if (needs_extra_trb && dwc3_calc_trbs_left(dep) <= 2 &&
- sg_dma_len(sg_next(s)) >= length)
+ if (num_trbs_left == 1 || (needs_extra_trb &&
+ num_trbs_left <= 2 &&
+ sg_dma_len(sg_next(s)) >= length))
must_interrupt = true;
dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
@@ -1230,7 +1231,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
break;
}
- if (!dwc3_calc_trbs_left(dep) || must_interrupt)
+ if (must_interrupt)
break;
}