From 1abf160f23de2a8539fe3cc170bec31cf70540da Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Tue, 16 Jun 2015 14:43:51 -0700 Subject: [PATCH] usb: dwc3: Allocate TRB pool upon enabling endpoint Currently gadget driver is by default allocating dma TRB pool per endpoint for 30 endpoints upon driver probe. Optimize this by allocating dma memory only for enabled endpoints. Change-Id: I378a42d0b84fa43f7c20cd025cd9361c467cb41b Signed-off-by: Hemant Kumar --- drivers/usb/dwc3/debugfs.c | 2 ++ drivers/usb/dwc3/gadget.c | 27 +++++++++++---------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 4312a8f86e57..7a886714d72b 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -738,6 +738,8 @@ static int dwc3_ep_trbs_show(struct seq_file *s, void *unused) spin_lock_irqsave(&dwc->lock, flags); dep = dwc->eps[ep_num]; + if (!dep->trb_pool) + return 0; seq_printf(s, "%s trb pool: flags:0x%x freeslot:%d busyslot:%d\n", dep->name, dep->flags, dep->free_slot, dep->busy_slot); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 7c15e8bdd66d..a9186eac9f2b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -386,7 +386,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep) dep->trb_pool = dma_zalloc_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM, - &dep->trb_pool_dma, GFP_KERNEL); + &dep->trb_pool_dma, GFP_ATOMIC); if (!dep->trb_pool) { dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n", dep->name); @@ -659,14 +659,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) dep->number >> 1, (dep->number & 1) ? "in" : "out"); - /* - * Clean up ep ring to avoid getting xferInProgress due to stale trbs - * with HWO bit set from previous composition when update transfer cmd - * is issued. - */ - memset(&dep->trb_pool[0], 0, sizeof(struct dwc3_trb) * DWC3_TRB_NUM); - dbg_event(dep->number, "Clr_TRB", 0); - return 0; } @@ -713,6 +705,12 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep, return 0; } + if (dep->number > 1) { + ret = dwc3_alloc_trb_pool(dep); + if (ret) + return ret; + } + spin_lock_irqsave(&dwc->lock, flags); ret = __dwc3_gadget_ep_enable(dep, desc, ep->comp_desc, false, false); dbg_event(dep->number, "ENABLE", ret); @@ -747,6 +745,8 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep) dbg_event(dep->number, "DISABLE", ret); spin_unlock_irqrestore(&dwc->lock, flags); + dwc3_free_trb_pool(dep); + return ret; } @@ -1965,17 +1965,11 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, if (!epnum) dwc->gadget.ep0 = &dep->endpoint; } else { - int ret; - usb_ep_set_maxpacket_limit(&dep->endpoint, 1024); dep->endpoint.max_streams = 15; dep->endpoint.ops = &dwc3_gadget_ep_ops; list_add_tail(&dep->endpoint.ep_list, &dwc->gadget.ep_list); - - ret = dwc3_alloc_trb_pool(dep); - if (ret) - return ret; } if (epnum == 0 || epnum == 1) { @@ -2038,7 +2032,8 @@ static void dwc3_gadget_free_endpoints(struct dwc3 *dwc) * with all sorts of bugs when removing dwc3.ko. */ if (epnum != 0 && epnum != 1) { - dwc3_free_trb_pool(dep); + if (dep->trb_pool) + dwc3_free_trb_pool(dep); list_del(&dep->endpoint.ep_list); }