usb: dwc3: Allocate fixed h/w eps for GSI endpoints

Adds support to allocate specific hardware EPs to
GSI enabled endpoints. Creates EP list with names
"gsi-epin" for IN and "gsi-epout" for OUT EPs that
are intended for use by the GSI function driver.
The EPs are reserved from the end of the EP list.

CRs-Fixed: 1003784
Change-Id: I70ebce8c2717baaea38f7b6235976d8a522eb9fd
Signed-off-by: Devdutt Patnaik <dpatnaik@codeaurora.org>
This commit is contained in:
Devdutt Patnaik 2016-01-25 12:50:22 -08:00 committed by Jeevan Shriram
parent 5488a16eb9
commit a431c4747f
2 changed files with 38 additions and 11 deletions

View file

@ -1053,11 +1053,6 @@ static void gsi_free_trbs(struct usb_ep *ep)
dep->trb_pool = NULL;
dep->trb_pool_dma = 0;
dep->trb_dma_pool = NULL;
/*
* Reset the ep_type to NORMAL, for next compostion
* switch which may be non-gsi.
*/
dep->endpoint.ep_type = EP_TYPE_NORMAL;
}
}
/*
@ -1078,9 +1073,6 @@ static void gsi_configure_ep(struct usb_ep *ep, struct usb_gsi_request *request)
memset(&params, 0x00, sizeof(params));
/* Set the ep_type as GSI */
dep->endpoint.ep_type = EP_TYPE_GSI;
/* Configure GSI EP */
params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc))
| DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc));

View file

@ -754,6 +754,13 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep)
return 0;
}
/* Keep GSI ep names with "-gsi" suffix */
if (!strnstr(dep->name, "gsi", 10)) {
snprintf(dep->name, sizeof(dep->name), "ep%d%s",
dep->number >> 1,
(dep->number & 1) ? "in" : "out");
}
spin_lock_irqsave(&dwc->lock, flags);
ret = __dwc3_gadget_ep_disable(dep);
dbg_event(dep->number, "DISABLE", ret);
@ -2142,11 +2149,27 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
/* -------------------------------------------------------------------------- */
#define NUM_GSI_OUT_EPS 1
#define NUM_GSI_IN_EPS 2
static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
u8 num, u32 direction)
{
struct dwc3_ep *dep;
u8 i;
u8 i, gsi_ep_count, gsi_ep_index = 0;
/* Read number of event buffers to check if we need
* to update gsi_ep_count. For non GSI targets this
* will be 0 and we will skip reservation of GSI eps.
* There is one event buffer for each GSI EP.
*/
gsi_ep_count = dwc->num_gsi_event_buffers;
/* OUT GSI EPs based on direction field */
if (gsi_ep_count && !direction)
gsi_ep_count = NUM_GSI_OUT_EPS;
/* IN GSI EPs */
else if (gsi_ep_count && direction)
gsi_ep_count = NUM_GSI_IN_EPS;
for (i = 0; i < num; i++) {
u8 epnum = (i << 1) | (!!direction);
@ -2160,9 +2183,21 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
dep->direction = !!direction;
dwc->eps[epnum] = dep;
snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,
(epnum & 1) ? "in" : "out");
/* Reserve EPs at the end for GSI based on gsi_ep_count */
if ((gsi_ep_index < gsi_ep_count) &&
(i > (num - 1 - gsi_ep_count))) {
gsi_ep_index++;
/* For GSI EPs, name eps as "gsi-epin" or "gsi-epout" */
snprintf(dep->name, sizeof(dep->name), "%s",
(epnum & 1) ? "gsi-epin" : "gsi-epout");
/* Set ep type as GSI */
dep->endpoint.ep_type = EP_TYPE_GSI;
} else {
snprintf(dep->name, sizeof(dep->name), "ep%d%s",
epnum >> 1, (epnum & 1) ? "in" : "out");
}
dep->endpoint.ep_num = epnum >> 1;
dep->endpoint.name = dep->name;
dwc3_trace(trace_dwc3_gadget, "initializing %s", dep->name);