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>
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 990d77d..3f5fad2 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -862,6 +862,13 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep)
dep->name))
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);
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -2218,11 +2225,22 @@ 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;
+
+ gsi_ep_count = NUM_GSI_OUT_EPS + NUM_GSI_IN_EPS;
+ /* 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 ? 1 : 0);
@@ -2237,9 +2255,21 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
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;
spin_lock_init(&dep->lock);