diff options
Diffstat (limited to 'drivers/usb/musb/musb_cppi41.c')
-rw-r--r-- | drivers/usb/musb/musb_cppi41.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 47ae6455d073..3ee133f675ab 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -39,6 +39,7 @@ struct cppi41_dma_channel { | |||
39 | u32 transferred; | 39 | u32 transferred; |
40 | u32 packet_sz; | 40 | u32 packet_sz; |
41 | struct list_head tx_check; | 41 | struct list_head tx_check; |
42 | int tx_zlp; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | #define MUSB_DMA_NUM_CHANNELS 15 | 45 | #define MUSB_DMA_NUM_CHANNELS 15 |
@@ -122,6 +123,8 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
122 | { | 123 | { |
123 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | 124 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; |
124 | struct musb *musb = hw_ep->musb; | 125 | struct musb *musb = hw_ep->musb; |
126 | void __iomem *epio = hw_ep->regs; | ||
127 | u16 csr; | ||
125 | 128 | ||
126 | if (!cppi41_channel->prog_len || | 129 | if (!cppi41_channel->prog_len || |
127 | (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) { | 130 | (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) { |
@@ -131,15 +134,24 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
131 | cppi41_channel->transferred; | 134 | cppi41_channel->transferred; |
132 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; | 135 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; |
133 | cppi41_channel->channel.rx_packet_done = true; | 136 | cppi41_channel->channel.rx_packet_done = true; |
137 | |||
138 | /* | ||
139 | * transmit ZLP using PIO mode for transfers which size is | ||
140 | * multiple of EP packet size. | ||
141 | */ | ||
142 | if (cppi41_channel->tx_zlp && (cppi41_channel->transferred % | ||
143 | cppi41_channel->packet_sz) == 0) { | ||
144 | musb_ep_select(musb->mregs, hw_ep->epnum); | ||
145 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY; | ||
146 | musb_writew(epio, MUSB_TXCSR, csr); | ||
147 | } | ||
134 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); | 148 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); |
135 | } else { | 149 | } else { |
136 | /* next iteration, reload */ | 150 | /* next iteration, reload */ |
137 | struct dma_chan *dc = cppi41_channel->dc; | 151 | struct dma_chan *dc = cppi41_channel->dc; |
138 | struct dma_async_tx_descriptor *dma_desc; | 152 | struct dma_async_tx_descriptor *dma_desc; |
139 | enum dma_transfer_direction direction; | 153 | enum dma_transfer_direction direction; |
140 | u16 csr; | ||
141 | u32 remain_bytes; | 154 | u32 remain_bytes; |
142 | void __iomem *epio = cppi41_channel->hw_ep->regs; | ||
143 | 155 | ||
144 | cppi41_channel->buf_addr += cppi41_channel->packet_sz; | 156 | cppi41_channel->buf_addr += cppi41_channel->packet_sz; |
145 | 157 | ||
@@ -363,6 +375,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, | |||
363 | cppi41_channel->total_len = len; | 375 | cppi41_channel->total_len = len; |
364 | cppi41_channel->transferred = 0; | 376 | cppi41_channel->transferred = 0; |
365 | cppi41_channel->packet_sz = packet_sz; | 377 | cppi41_channel->packet_sz = packet_sz; |
378 | cppi41_channel->tx_zlp = (cppi41_channel->is_tx && mode) ? 1 : 0; | ||
366 | 379 | ||
367 | /* | 380 | /* |
368 | * Due to AM335x' Advisory 1.0.13 we are not allowed to transfer more | 381 | * Due to AM335x' Advisory 1.0.13 we are not allowed to transfer more |