usb: dwc3: calculate number of event buffers dynamically
authorFelipe Balbi <balbi@ti.com>
Wed, 12 Oct 2011 07:31:04 +0000 (10:31 +0300)
committerFelipe Balbi <balbi@ti.com>
Mon, 12 Dec 2011 09:48:11 +0000 (11:48 +0200)
This will allow us to only allocate memory when
we actually need.

Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c

index ca3b01f5fffa52761d9894a2b648a094a68370c3..1f67606fd4fb5912c8c37687a32d5e15f18922b5 100644 (file)
@@ -154,7 +154,7 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
        struct dwc3_event_buffer        *evt;
        int i;
 
-       for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {
+       for (i = 0; i < dwc->num_event_buffers; i++) {
                evt = dwc->ev_buffs[i];
                if (evt) {
                        dwc3_free_one_event_buffer(dwc, evt);
@@ -166,17 +166,19 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
 /**
  * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
  * @dwc: Pointer to out controller context structure
- * @num: number of event buffers to allocate
  * @length: size of event buffer
  *
  * Returns 0 on success otherwise negative errno. In error the case, dwc
  * may contain some buffers allocated but not all which were requested.
  */
-static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned num,
-               unsigned length)
+static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
 {
+       int                     num;
        int                     i;
 
+       num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
+       dwc->num_event_buffers = num;
+
        for (i = 0; i < num; i++) {
                struct dwc3_event_buffer        *evt;
 
@@ -202,7 +204,7 @@ static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc)
        struct dwc3_event_buffer        *evt;
        int                             n;
 
-       for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
+       for (n = 0; n < dwc->num_event_buffers; n++) {
                evt = dwc->ev_buffs[n];
                dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",
                                evt->buf, (unsigned long long) evt->dma,
@@ -225,7 +227,7 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
        struct dwc3_event_buffer        *evt;
        int                             n;
 
-       for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
+       for (n = 0; n < dwc->num_event_buffers; n++) {
                evt = dwc->ev_buffs[n];
                dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
                dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
@@ -289,8 +291,9 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
                cpu_relax();
        } while (true);
 
-       ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_NUM,
-                       DWC3_EVENT_BUFFERS_SIZE);
+       dwc3_cache_hwparams(dwc);
+
+       ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
        if (ret) {
                dev_err(dwc->dev, "failed to allocate event buffers\n");
                ret = -ENOMEM;
@@ -303,8 +306,6 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
                goto err1;
        }
 
-       dwc3_cache_hwparams(dwc);
-
        return 0;
 
 err1:
index b7d56c3a1fbb1bcc5cd671b7a625ff17641cab1f..4b6c673ed6085c6bbb83e395641c50e46443b052 100644 (file)
@@ -52,7 +52,7 @@
 /* Global constants */
 #define DWC3_ENDPOINTS_NUM     32
 
-#define DWC3_EVENT_BUFFERS_NUM 2
+#define DWC3_EVENT_BUFFERS_MAX 2
 #define DWC3_EVENT_BUFFERS_SIZE        PAGE_SIZE
 #define DWC3_EVENT_TYPE_MASK   0xfe
 
@@ -536,6 +536,8 @@ struct dwc3_hwparams {
        u32     hwparams8;
 };
 
+#define DWC3_NUM_INT(n)        (((n) & (0x3f << 15)) >> 15)
+
 /**
  * struct dwc3 - representation of our controller
  * @ctrl_req: usb control request which is used for ep0
@@ -555,6 +557,7 @@ struct dwc3_hwparams {
  * @regs: base address for our registers
  * @regs_size: address space size
  * @irq: IRQ number
+ * @num_event_buffers: calculated number of event buffers
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
  * @revision: revision register contents
  * @is_selfpowered: true when we are selfpowered
@@ -585,7 +588,7 @@ struct dwc3 {
        spinlock_t              lock;
        struct device           *dev;
 
-       struct dwc3_event_buffer *ev_buffs[DWC3_EVENT_BUFFERS_NUM];
+       struct dwc3_event_buffer *ev_buffs[DWC3_EVENT_BUFFERS_MAX];
        struct dwc3_ep          *eps[DWC3_ENDPOINTS_NUM];
 
        struct usb_gadget       gadget;
@@ -596,6 +599,7 @@ struct dwc3 {
 
        int                     irq;
 
+       u32                     num_event_buffers;
        u32                     maximum_speed;
        u32                     revision;
 
index 807737aec00e7029463ce91e811b90493206de8e..b84418e887740599c00d3e257b34657f1a4f190f 100644 (file)
@@ -1925,7 +1925,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
 
        spin_lock(&dwc->lock);
 
-       for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {
+       for (i = 0; i < dwc->num_event_buffers; i++) {
                irqreturn_t status;
 
                status = dwc3_process_event_buf(dwc, i);