diff options
Diffstat (limited to 'drivers/usb/musb/musbhsdma.c')
-rw-r--r-- | drivers/usb/musb/musbhsdma.c | 66 |
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 | } |