diff options
Diffstat (limited to 'drivers/usb/musb/musbhsdma.c')
-rw-r--r-- | drivers/usb/musb/musbhsdma.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 5e83f96d6b77..1008044a3bbc 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/device.h> | 33 | #include <linux/device.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/slab.h> | ||
36 | #include "musb_core.h" | 37 | #include "musb_core.h" |
37 | #include "musbhsdma.h" | 38 | #include "musbhsdma.h" |
38 | 39 | ||
@@ -250,14 +251,38 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
250 | u8 bchannel; | 251 | u8 bchannel; |
251 | u8 int_hsdma; | 252 | u8 int_hsdma; |
252 | 253 | ||
253 | u32 addr; | 254 | u32 addr, count; |
254 | u16 csr; | 255 | u16 csr; |
255 | 256 | ||
256 | spin_lock_irqsave(&musb->lock, flags); | 257 | spin_lock_irqsave(&musb->lock, flags); |
257 | 258 | ||
258 | int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR); | 259 | int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR); |
259 | if (!int_hsdma) | 260 | |
260 | goto done; | 261 | #ifdef CONFIG_BLACKFIN |
262 | /* Clear DMA interrupt flags */ | ||
263 | musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma); | ||
264 | #endif | ||
265 | |||
266 | if (!int_hsdma) { | ||
267 | DBG(2, "spurious DMA irq\n"); | ||
268 | |||
269 | for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { | ||
270 | musb_channel = (struct musb_dma_channel *) | ||
271 | &(controller->channel[bchannel]); | ||
272 | channel = &musb_channel->channel; | ||
273 | if (channel->status == MUSB_DMA_STATUS_BUSY) { | ||
274 | count = musb_read_hsdma_count(mbase, bchannel); | ||
275 | |||
276 | if (count == 0) | ||
277 | int_hsdma |= (1 << bchannel); | ||
278 | } | ||
279 | } | ||
280 | |||
281 | DBG(2, "int_hsdma = 0x%x\n", int_hsdma); | ||
282 | |||
283 | if (!int_hsdma) | ||
284 | goto done; | ||
285 | } | ||
261 | 286 | ||
262 | for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { | 287 | for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { |
263 | if (int_hsdma & (1 << bchannel)) { | 288 | if (int_hsdma & (1 << bchannel)) { |
@@ -280,7 +305,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
280 | channel->actual_len = addr | 305 | channel->actual_len = addr |
281 | - musb_channel->start_addr; | 306 | - musb_channel->start_addr; |
282 | 307 | ||
283 | DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n", | 308 | DBG(2, "ch %p, 0x%x -> 0x%x (%zu / %d) %s\n", |
284 | channel, musb_channel->start_addr, | 309 | channel, musb_channel->start_addr, |
285 | addr, channel->actual_len, | 310 | addr, channel->actual_len, |
286 | musb_channel->len, | 311 | musb_channel->len, |
@@ -324,11 +349,6 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) | |||
324 | } | 349 | } |
325 | } | 350 | } |
326 | 351 | ||
327 | #ifdef CONFIG_BLACKFIN | ||
328 | /* Clear DMA interrup flags */ | ||
329 | musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma); | ||
330 | #endif | ||
331 | |||
332 | retval = IRQ_HANDLED; | 352 | retval = IRQ_HANDLED; |
333 | done: | 353 | done: |
334 | spin_unlock_irqrestore(&musb->lock, flags); | 354 | spin_unlock_irqrestore(&musb->lock, flags); |