OSDN Git Service

usb: dwc3: Allocate TRB pool upon enabling endpoint
authorHemant Kumar <hemantk@codeaurora.org>
Tue, 16 Jun 2015 21:43:51 +0000 (14:43 -0700)
committerDavid Keitel <dkeitel@codeaurora.org>
Tue, 22 Mar 2016 18:06:56 +0000 (11:06 -0700)
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 <hemantk@codeaurora.org>
drivers/usb/dwc3/debugfs.c
drivers/usb/dwc3/gadget.c

index 4312a8f..7a88671 100644 (file)
@@ -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);
index 7c15e8b..a9186ea 100644 (file)
@@ -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);
                }