Commit 4bc48c97 authored by Felipe Balbi's avatar Felipe Balbi

usb: dwc3: gadget: retire LST bit completely

The only endpoint which actually requires LST bit
and XferComplete is ep0/1. Let's save some time by
completely removing LST bit support and
XferComplete.

This simplifies and consolidates endpoint handling
for all other 3 transfer types while also avoiding
extra interrupts.
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent fa8410b3
...@@ -490,6 +490,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, ...@@ -490,6 +490,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
params.param0 |= DWC3_DEPCFG_ACTION_INIT; params.param0 |= DWC3_DEPCFG_ACTION_INIT;
} }
if (usb_endpoint_xfer_control(desc))
params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN; params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN;
if (dep->number <= 1 || usb_endpoint_xfer_isoc(desc)) if (dep->number <= 1 || usb_endpoint_xfer_isoc(desc))
...@@ -771,15 +772,13 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep, ...@@ -771,15 +772,13 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
*/ */
static void dwc3_prepare_one_trb(struct dwc3_ep *dep, static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
struct dwc3_request *req, dma_addr_t dma, struct dwc3_request *req, dma_addr_t dma,
unsigned length, unsigned last, unsigned chain, unsigned node) unsigned length, unsigned chain, unsigned node)
{ {
struct dwc3_trb *trb; struct dwc3_trb *trb;
dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s%s", dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s",
dep->name, req, (unsigned long long) dma, dep->name, req, (unsigned long long) dma,
length, last ? " last" : "", length, chain ? " chain" : "");
chain ? " chain" : "");
trb = &dep->trb_pool[dep->trb_enqueue]; trb = &dep->trb_pool[dep->trb_enqueue];
...@@ -829,9 +828,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, ...@@ -829,9 +828,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
if (!req->request.no_interrupt && !chain) if (!req->request.no_interrupt && !chain)
trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI; trb->ctrl |= DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI;
if (last && !usb_endpoint_xfer_isoc(dep->endpoint.desc))
trb->ctrl |= DWC3_TRB_CTRL_LST;
if (chain) if (chain)
trb->ctrl |= DWC3_TRB_CTRL_CHN; trb->ctrl |= DWC3_TRB_CTRL_CHN;
...@@ -894,13 +890,11 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) ...@@ -894,13 +890,11 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
} }
static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
struct dwc3_request *req, unsigned int trbs_left, struct dwc3_request *req, unsigned int trbs_left)
unsigned int more_coming)
{ {
struct usb_request *request = &req->request; struct usb_request *request = &req->request;
struct scatterlist *sg = request->sg; struct scatterlist *sg = request->sg;
struct scatterlist *s; struct scatterlist *s;
unsigned int last = false;
unsigned int length; unsigned int length;
dma_addr_t dma; dma_addr_t dma;
int i; int i;
...@@ -911,48 +905,28 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, ...@@ -911,48 +905,28 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
length = sg_dma_len(s); length = sg_dma_len(s);
dma = sg_dma_address(s); dma = sg_dma_address(s);
if (sg_is_last(s)) { if (sg_is_last(s))
if (usb_endpoint_xfer_int(dep->endpoint.desc) ||
!more_coming)
last = true;
chain = false;
}
if (!trbs_left--)
last = true;
if (last)
chain = false; chain = false;
dwc3_prepare_one_trb(dep, req, dma, length, dwc3_prepare_one_trb(dep, req, dma, length,
last, chain, i); chain, i);
if (last) if (!trbs_left--)
break; break;
} }
} }
static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
struct dwc3_request *req, unsigned int trbs_left, struct dwc3_request *req, unsigned int trbs_left)
unsigned int more_coming)
{ {
unsigned int last = false;
unsigned int length; unsigned int length;
dma_addr_t dma; dma_addr_t dma;
dma = req->request.dma; dma = req->request.dma;
length = req->request.length; length = req->request.length;
if (!trbs_left)
last = true;
/* Is this the last request? */
if (usb_endpoint_xfer_int(dep->endpoint.desc) || !more_coming)
last = true;
dwc3_prepare_one_trb(dep, req, dma, length, dwc3_prepare_one_trb(dep, req, dma, length,
last, false, 0); false, 0);
} }
/* /*
...@@ -966,7 +940,6 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, ...@@ -966,7 +940,6 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
static void dwc3_prepare_trbs(struct dwc3_ep *dep) static void dwc3_prepare_trbs(struct dwc3_ep *dep)
{ {
struct dwc3_request *req, *n; struct dwc3_request *req, *n;
unsigned int more_coming;
u32 trbs_left; u32 trbs_left;
BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
...@@ -975,15 +948,11 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) ...@@ -975,15 +948,11 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
if (!trbs_left) if (!trbs_left)
return; return;
more_coming = dep->allocated_requests - dep->queued_requests;
list_for_each_entry_safe(req, n, &dep->pending_list, list) { list_for_each_entry_safe(req, n, &dep->pending_list, list) {
if (req->request.num_mapped_sgs > 0) if (req->request.num_mapped_sgs > 0)
dwc3_prepare_one_trb_sg(dep, req, trbs_left--, dwc3_prepare_one_trb_sg(dep, req, trbs_left--);
more_coming);
else else
dwc3_prepare_one_trb_linear(dep, req, trbs_left--, dwc3_prepare_one_trb_linear(dep, req, trbs_left--);
more_coming);
if (!trbs_left) if (!trbs_left)
return; return;
...@@ -1127,8 +1096,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) ...@@ -1127,8 +1096,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
* This will save one IRQ (XFER_NOT_READY) and possibly make it a * This will save one IRQ (XFER_NOT_READY) and possibly make it a
* little bit faster. * little bit faster.
*/ */
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
!usb_endpoint_xfer_int(dep->endpoint.desc)) {
ret = __dwc3_gadget_kick_transfer(dep, 0); ret = __dwc3_gadget_kick_transfer(dep, 0);
goto out; goto out;
} }
...@@ -2045,7 +2013,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, ...@@ -2045,7 +2013,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
int chain; int chain;
req = next_request(&dep->started_list); req = next_request(&dep->started_list);
if (WARN_ON_ONCE(!req)) if (!req)
return 1; return 1;
chain = req->request.num_mapped_sgs > 0; chain = req->request.num_mapped_sgs > 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment