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.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 8662e9e159c3..5e83f96d6b77 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -195,30 +195,32 @@ static int dma_channel_abort(struct dma_channel *channel)
195 void __iomem *mbase = musb_channel->controller->base; 195 void __iomem *mbase = musb_channel->controller->base;
196 196
197 u8 bchannel = musb_channel->idx; 197 u8 bchannel = musb_channel->idx;
198 int offset;
198 u16 csr; 199 u16 csr;
199 200
200 if (channel->status == MUSB_DMA_STATUS_BUSY) { 201 if (channel->status == MUSB_DMA_STATUS_BUSY) {
201 if (musb_channel->transmit) { 202 if (musb_channel->transmit) {
202 203 offset = MUSB_EP_OFFSET(musb_channel->epnum,
203 csr = musb_readw(mbase, 204 MUSB_TXCSR);
204 MUSB_EP_OFFSET(musb_channel->epnum, 205
205 MUSB_TXCSR)); 206 /*
206 csr &= ~(MUSB_TXCSR_AUTOSET | 207 * The programming guide says that we must clear
207 MUSB_TXCSR_DMAENAB | 208 * the DMAENAB bit before the DMAMODE bit...
208 MUSB_TXCSR_DMAMODE); 209 */
209 musb_writew(mbase, 210 csr = musb_readw(mbase, offset);
210 MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR), 211 csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
211 csr); 212 musb_writew(mbase, offset, csr);
213 csr &= ~MUSB_TXCSR_DMAMODE;
214 musb_writew(mbase, offset, csr);
212 } else { 215 } else {
213 csr = musb_readw(mbase, 216 offset = MUSB_EP_OFFSET(musb_channel->epnum,
214 MUSB_EP_OFFSET(musb_channel->epnum, 217 MUSB_RXCSR);
215 MUSB_RXCSR)); 218
219 csr = musb_readw(mbase, offset);
216 csr &= ~(MUSB_RXCSR_AUTOCLEAR | 220 csr &= ~(MUSB_RXCSR_AUTOCLEAR |
217 MUSB_RXCSR_DMAENAB | 221 MUSB_RXCSR_DMAENAB |
218 MUSB_RXCSR_DMAMODE); 222 MUSB_RXCSR_DMAMODE);
219 musb_writew(mbase, 223 musb_writew(mbase, offset, csr);
220 MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
221 csr);
222 } 224 }
223 225
224 musb_writew(mbase, 226 musb_writew(mbase,
@@ -296,20 +298,28 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
296 && ((channel->desired_mode == 0) 298 && ((channel->desired_mode == 0)
297 || (channel->actual_len & 299 || (channel->actual_len &
298 (musb_channel->max_packet_sz - 1))) 300 (musb_channel->max_packet_sz - 1)))
299 ) { 301 ) {
302 u8 epnum = musb_channel->epnum;
303 int offset = MUSB_EP_OFFSET(epnum,
304 MUSB_TXCSR);
305 u16 txcsr;
306
307 /*
308 * The programming guide says that we
309 * must clear DMAENAB before DMAMODE.
310 */
311 musb_ep_select(mbase, epnum);
312 txcsr = musb_readw(mbase, offset);
313 txcsr &= ~(MUSB_TXCSR_DMAENAB
314 | MUSB_TXCSR_AUTOSET);
315 musb_writew(mbase, offset, txcsr);
300 /* Send out the packet */ 316 /* Send out the packet */
301 musb_ep_select(mbase, 317 txcsr &= ~MUSB_TXCSR_DMAMODE;
302 musb_channel->epnum); 318 txcsr |= MUSB_TXCSR_TXPKTRDY;
303 musb_writew(mbase, MUSB_EP_OFFSET( 319 musb_writew(mbase, offset, txcsr);
304 musb_channel->epnum,
305 MUSB_TXCSR),
306 MUSB_TXCSR_TXPKTRDY);
307 } else {
308 musb_dma_completion(
309 musb,
310 musb_channel->epnum,
311 musb_channel->transmit);
312 } 320 }
321 musb_dma_completion(musb, musb_channel->epnum,
322 musb_channel->transmit);
313 } 323 }
314 } 324 }
315 } 325 }