[PATCH] USB: musb: allow unaligned memory data transfers

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

 



On MUSB:IP rev RTL1.8 and above(OMAP3630, OMAP4),
DMA addresses have to be word aligned.

g-ether gadget passes unaligned buffers to the controller
For such buffers, dma fails and a fall back mechanism of interrupt
mode is used

Validated on Zoom3 with g-ether diver

Signed-off-by: Anand Gadiyar <gadiyar@xxxxxx>
Signed-off-by: Vikram Pandita <vikram.pandita@xxxxxx>
Cc: Maulik Mankad <x0082077@xxxxxx>
Cc: Nilkesh Patra <nilkesh.patra@xxxxxx>
Cc: Felipe Balbi <felipe.balbi@xxxxxxxxx>
---
 drivers/usb/musb/musb_gadget.c |    9 ++++++++-
 drivers/usb/musb/musbhsdma.c   |   11 +++++++++++
 2 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index cbcf14a..7ad3571 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -681,8 +681,15 @@ static void rxstate(struct musb *musb, struct musb_request *req)
 							transfer_size);
 				}
 
-				if (use_dma)
+				if (use_dma) {
 					return;
+				} else {
+					/* Need to clear DMAENAB for the
+					 * backup PIO mode transfer to work
+					 */
+					csr &= ~MUSB_RXCSR_DMAENAB;
+					musb_writew(epio, MUSB_RXCSR, csr);
+				}
 			}
 #endif	/* Mentor's DMA */
 
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index a237550..f118ae2 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -166,6 +166,8 @@ static int dma_channel_program(struct dma_channel *channel,
 				dma_addr_t dma_addr, u32 len)
 {
 	struct musb_dma_channel *musb_channel = channel->private_data;
+	struct musb_dma_controller *controller = musb_channel->controller;
+	struct musb *musb = controller->private_data;
 
 	DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
 		musb_channel->epnum,
@@ -175,6 +177,15 @@ static int dma_channel_program(struct dma_channel *channel,
 	BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
 		channel->status == MUSB_DMA_STATUS_BUSY);
 
+	/* On MUSB:RTL1.8 and above, DMA has to be word aligned */
+	if ((dma_addr % 4) &&
+		(musb->hwvers >= MUSB_HWVERS_1800)) {
+		/* Fail DMA for unaligned buffers:
+		 * Use PIO for such buffers
+		 */
+		return false;
+	}
+
 	channel->actual_len = 0;
 	musb_channel->start_addr = dma_addr;
 	musb_channel->len = len;
-- 
1.6.6.rc0.66.ge160d

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

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux