diff mbox

[2/5] musb: use system DMA to fix Inventra DMA issue on RTL-1.4

Message ID 19F8576C6E063C45BE387C64729E7394044E4052E6@dbde02.ent.ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ajay Kumar Gupta May 13, 2010, 10:10 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index fd842af..477a009 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -297,9 +297,13 @@  static void txstate(struct musb *musb, struct musb_request *req)
 			csr);
 
 #ifndef	CONFIG_MUSB_PIO_ONLY
-	if (is_dma_capable() && musb_ep->dma) {
+
+	if (is_dma_capable() && musb->dma_controller) {
 		struct dma_controller	*c = musb->dma_controller;
 
+		if (!musb_ep->dma)
+			musb_ep->dma = c->channel_alloc(c, musb_ep->hw_ep, 1);
+
 		use_dma = (request->dma != DMA_ADDR_INVALID);
 
 		/* MUSB_TXCSR_P_ISO is still set correctly */
@@ -433,6 +437,7 @@  void musb_g_tx(struct musb *musb, u8 epnum)
 	u8 __iomem		*mbase = musb->mregs;
 	struct musb_ep		*musb_ep = &musb->endpoints[epnum].ep_in;
 	void __iomem		*epio = musb->endpoints[epnum].regs;
+	struct dma_controller	*c = musb->dma_controller;
 	struct dma_channel	*dma;
 
 	musb_ep_select(mbase, epnum);
@@ -535,6 +540,10 @@  void musb_g_tx(struct musb *musb, u8 epnum)
 			if (!request) {
 				DBG(4, "%s idle now\n",
 					musb_ep->end_point.name);
+				if (musb_ep->dma) {
+					c->channel_release(musb_ep->dma);
+					musb_ep->dma = NULL;
+				}
 				return;
 			}
 		}
@@ -585,6 +594,7 @@  static void rxstate(struct musb *musb, struct musb_request *req)
 	struct usb_request	*request = &req->request;
 	struct musb_ep		*musb_ep = &musb->endpoints[epnum].ep_out;
 	void __iomem		*epio = musb->endpoints[epnum].regs;
+	struct dma_controller	*c = musb->dma_controller;
 	unsigned		fifo_count = 0;
 	u16			len = musb_ep->packet_sz;
 	u16			csr = musb_readw(epio, MUSB_RXCSR);
@@ -601,8 +611,10 @@  static void rxstate(struct musb *musb, struct musb_request *req)
 		return;
 	}
 
+	if (is_dma_capable() && musb->dma_controller && !musb_ep->dma)
+		musb_ep->dma = c->channel_alloc(c, musb_ep->hw_ep, 0);
+
 	if ((is_cppi_enabled() || is_cppi41_enabled()) && musb_ep->dma) {
-		struct dma_controller	*c = musb->dma_controller;
 		struct dma_channel	*channel = musb_ep->dma;
 
 		/* NOTE:  CPPI won't actually stop advancing the DMA
@@ -633,11 +645,9 @@  static void rxstate(struct musb *musb, struct musb_request *req)
 		if (request->actual < request->length) {
 #ifdef CONFIG_USB_INVENTRA_DMA
 			if (is_dma_capable() && musb_ep->dma) {
-				struct dma_controller	*c;
 				struct dma_channel	*channel;
 				int			use_dma = 0;
 
-				c = musb->dma_controller;
 				channel = musb_ep->dma;
 
 	/* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
@@ -719,7 +729,6 @@  static void rxstate(struct musb *musb, struct musb_request *req)
 
 #ifdef	CONFIG_USB_TUSB_OMAP_DMA
 			if (tusb_dma_omap() && musb_ep->dma) {
-				struct dma_controller *c = musb->dma_controller;
 				struct dma_channel *channel = musb_ep->dma;
 				u32 dma_addr = request->dma + request->actual;
 				int ret;
@@ -764,6 +773,7 @@  void musb_g_rx(struct musb *musb, u8 epnum)
 	void __iomem		*mbase = musb->mregs;
 	struct musb_ep		*musb_ep = &musb->endpoints[epnum].ep_out;
 	void __iomem		*epio = musb->endpoints[epnum].regs;
+	struct dma_controller	*c = musb->dma_controller;
 	struct dma_channel	*dma;
 
 	musb_ep_select(mbase, epnum);
@@ -838,8 +848,13 @@  void musb_g_rx(struct musb *musb, u8 epnum)
 		musb_g_giveback(musb_ep, request, 0);
 
 		request = next_request(musb_ep);
-		if (!request)
+		if (!request) {
+			if (musb_ep->dma) {
+				c->channel_release(musb_ep->dma);
+				musb_ep->dma = NULL;
+			}
 			return;
+		}
 	}
 
 	/* analyze request if the ep is hot */
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 89c8c35..001a1d6 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -460,11 +460,21 @@  static void musb_advance_schedule(struct musb *musb, struct urb *urb,
 	 */
 	if (list_empty(&qh->hep->urb_list)) {
 		struct list_head	*head;
+		struct dma_controller	*dma = musb->dma_controller;
 
-		if (is_in)
+		if (is_in) {
 			ep->rx_reinit = 1;
-		else
+			if (ep->rx_channel) {
+				dma->channel_release(ep->rx_channel);
+				ep->rx_channel = NULL;
+			}
+		} else {
 			ep->tx_reinit = 1;
+			if (ep->tx_channel) {
+				dma->channel_release(ep->tx_channel);
+				ep->tx_channel = NULL;
+			}
+		}
 
 		/* Clobber old pointers to this qh */
 		musb_ep_set_qh(ep, is_in, NULL);