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