aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musbhsdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/musbhsdma.c')
-rw-r--r--drivers/usb/musb/musbhsdma.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 6f771af5cbdb..563114d613d6 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -158,6 +158,8 @@ static int dma_channel_program(struct dma_channel *channel,
158 dma_addr_t dma_addr, u32 len) 158 dma_addr_t dma_addr, u32 len)
159{ 159{
160 struct musb_dma_channel *musb_channel = channel->private_data; 160 struct musb_dma_channel *musb_channel = channel->private_data;
161 struct musb_dma_controller *controller = musb_channel->controller;
162 struct musb *musb = controller->private_data;
161 163
162 DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n", 164 DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
163 musb_channel->epnum, 165 musb_channel->epnum,
@@ -167,6 +169,18 @@ static int dma_channel_program(struct dma_channel *channel,
167 BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || 169 BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
168 channel->status == MUSB_DMA_STATUS_BUSY); 170 channel->status == MUSB_DMA_STATUS_BUSY);
169 171
172 /*
173 * The DMA engine in RTL1.8 and above cannot handle
174 * DMA addresses that are not aligned to a 4 byte boundary.
175 * It ends up masking the last two bits of the address
176 * programmed in DMA_ADDR.
177 *
178 * Fail such DMA transfers, so that the backup PIO mode
179 * can carry out the transfer
180 */
181 if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4))
182 return false;
183
170 channel->actual_len = 0; 184 channel->actual_len = 0;
171 musb_channel->start_addr = dma_addr; 185 musb_channel->start_addr = dma_addr;
172 musb_channel->len = len; 186 musb_channel->len = len;