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.c38
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;
333done: 353done:
334 spin_unlock_irqrestore(&musb->lock, flags); 354 spin_unlock_irqrestore(&musb->lock, flags);