[PATCH 12/14] usb: chipidea: udc: prepare qhead with dma_alloc_coherent

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

 



The prepared memory for the qhead needs to be contiguos and 2K aligned.
We change the code from allocating extra buffer for every ep qhead to
one big area. This patch lowers the amount of code to prepare the
memory.

Signed-off-by: Michael Grzeschik <m.grzeschik@xxxxxxxxxxxxxx>
---
 drivers/usb/chipidea/ci.h  |  6 ++++++
 drivers/usb/chipidea/udc.c | 33 +++++++++++++++------------------
 drivers/usb/chipidea/udc.h |  2 +-
 3 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 4ca3373..1e7cc61 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -158,6 +158,12 @@ struct ci13xxx {
 	struct dma_pool			*qh_pool;
 	struct dma_pool			*td_pool;
 
+	struct {
+		struct ci13xxx_qh	*ptr;
+		dma_addr_t		dma;
+		size_t			size;
+	}				qh;
+
 	struct usb_gadget		gadget;
 	struct usb_gadget_driver	*driver;
 	unsigned			hw_ep_max;
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 60a90c6..64089f2 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/irqreturn.h>
 #include <linux/kernel.h>
@@ -1403,8 +1404,8 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
 		if (is_active) {
 			pm_runtime_get_sync(&_gadget->dev);
 			hw_device_reset(ci, USBMODE_CM_DC);
-			hw_enable_vbus_intr(ci);
-			hw_device_state(ci, ci->ep0out->qh.dma);
+			hw_device_state(ci, ci->qh.dma);
+			dev_dbg(ci->dev, "Connected to host\n");
 		} else {
 			hw_device_state(ci, 0);
 			if (ci->platdata->notify_event)
@@ -1507,8 +1508,8 @@ static int init_eps(struct ci13xxx *ci)
 			mEp->ep.maxpacket = (unsigned short)~0;
 
 			INIT_LIST_HEAD(&mEp->qh.queue);
-			mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL,
-						     &mEp->qh.dma);
+			mEp->qh.ptr = &ci->qh.ptr[i * 2 + j];
+
 			if (mEp->qh.ptr == NULL)
 				retval = -ENOMEM;
 			else
@@ -1536,13 +1537,8 @@ static int init_eps(struct ci13xxx *ci)
 
 static void destroy_eps(struct ci13xxx *ci)
 {
-	int i;
-
-	for (i = 0; i < ci->hw_ep_max; i++) {
-		struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i];
-
-		dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma);
-	}
+	dma_free_coherent(ci->dev, ci->qh.size,
+		ci->qh.ptr, ci->qh.dma);
 }
 
 /**
@@ -1588,7 +1584,7 @@ static int ci13xxx_start(struct usb_gadget *gadget,
 		}
 	}
 
-	retval = hw_device_state(ci, ci->ep0out->qh.dma);
+	retval = hw_device_state(ci, ci->qh.dma);
 	if (retval)
 		pm_runtime_put_sync(&ci->gadget.dev);
 
@@ -1739,11 +1735,14 @@ static int udc_start(struct ci13xxx *ci)
 	ci->gadget.dev.parent   = dev;
 	ci->gadget.dev.release  = udc_release;
 
+	ci->qh.size = ci->hw_ep_max * sizeof(struct ci13xxx_qh);
+	ci->qh.size = ALIGN(ci->qh.size, SZ_2K);
+
 	/* alloc resources */
-	ci->qh_pool = dma_pool_create("ci13xxx_qh", dev,
-				       sizeof(struct ci13xxx_qh),
-				       64, CI13XXX_PAGE_SIZE);
-	if (ci->qh_pool == NULL)
+	ci->qh.ptr = dma_alloc_coherent(dev, ci->qh.size,
+					&ci->qh.dma, GFP_ATOMIC);
+
+	if (ci->qh.ptr == NULL)
 		return -ENOMEM;
 
 	ci->td_pool = dma_pool_create("ci13xxx_td", dev,
@@ -1817,7 +1816,6 @@ destroy_eps:
 free_pools:
 	dma_pool_destroy(ci->td_pool);
 free_qh_pool:
-	dma_pool_destroy(ci->qh_pool);
 	return retval;
 }
 
@@ -1839,7 +1837,6 @@ static void udc_stop(struct ci13xxx *ci)
 	destroy_eps(ci);
 
 	dma_pool_destroy(ci->td_pool);
-	dma_pool_destroy(ci->qh_pool);
 
 	if (!IS_ERR_OR_NULL(ci->transceiver)) {
 		otg_set_peripheral(ci->transceiver->otg, NULL);
diff --git a/drivers/usb/chipidea/udc.h b/drivers/usb/chipidea/udc.h
index be60464..46c5210 100644
--- a/drivers/usb/chipidea/udc.h
+++ b/drivers/usb/chipidea/udc.h
@@ -55,7 +55,7 @@ struct ci13xxx_qh {
 	/* 9 */
 	u32 RESERVED;
 	struct usb_ctrlrequest   setup;
-};
+} __attribute__ ((aligned (64)));
 
 /**
  * struct ci13xxx_req - usb request representation
-- 
1.8.2.rc2

--
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