[PATCH 03/34] usb: dwc3: calculate number of event buffers dynamically

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This will allow us to only allocate memory when
we actually need.

Signed-off-by: Felipe Balbi <balbi@xxxxxx>
---
 drivers/usb/dwc3/core.c   |   21 +++++++++++----------
 drivers/usb/dwc3/core.h   |    8 ++++++--
 drivers/usb/dwc3/gadget.c |    2 +-
 3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ca3b01f..1f67606 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -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:
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b7d56c3..4b6c673 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -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;
 
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 807737a..b84418e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -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);
-- 
1.7.8.rc3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux