Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 273868
b: refs/heads/master
c: 28da283
h: refs/heads/master
v: v3
  • Loading branch information
Viresh Kumar authored and Vinod Koul committed Aug 25, 2011
1 parent b557380 commit 8f90734
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 16ca8105040217acf5b4b506d04bb933fb3a76af
refs/heads/master: 28da28365da3f3bea1d4b7212a8a40e4b9ac3229
44 changes: 23 additions & 21 deletions trunk/drivers/dma/amba-pl08x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1619,38 +1619,40 @@ static void pl08x_tasklet(unsigned long data)
static irqreturn_t pl08x_irq(int irq, void *dev)
{
struct pl08x_driver_data *pl08x = dev;
u32 mask = 0;
u32 val;
int i;

val = readl(pl08x->base + PL080_ERR_STATUS);
if (val) {
/* An error interrupt (on one or more channels) */
dev_err(&pl08x->adev->dev,
"%s error interrupt, register value 0x%08x\n",
__func__, val);
/*
* Simply clear ALL PL08X error interrupts,
* regardless of channel and cause
* FIXME: should be 0x00000003 on PL081 really.
*/
writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR);
u32 mask = 0, err, tc, i;

/* check & clear - ERR & TC interrupts */
err = readl(pl08x->base + PL080_ERR_STATUS);
if (err) {
dev_err(&pl08x->adev->dev, "%s error interrupt, register value 0x%08x\n",
__func__, err);
writel(err, pl08x->base + PL080_ERR_CLEAR);
}
val = readl(pl08x->base + PL080_INT_STATUS);
tc = readl(pl08x->base + PL080_INT_STATUS);
if (tc)
writel(tc, pl08x->base + PL080_TC_CLEAR);

if (!err && !tc)
return IRQ_NONE;

for (i = 0; i < pl08x->vd->channels; i++) {
if ((1 << i) & val) {
if (((1 << i) & err) || ((1 << i) & tc)) {
/* Locate physical channel */
struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i];
struct pl08x_dma_chan *plchan = phychan->serving;

if (!plchan) {
dev_err(&pl08x->adev->dev,
"%s Error TC interrupt on unused channel: 0x%08x\n",
__func__, i);
continue;
}

/* Schedule tasklet on this channel */
tasklet_schedule(&plchan->tasklet);

mask |= (1 << i);
}
}
/* Clear only the terminal interrupts on channels we processed */
writel(mask, pl08x->base + PL080_TC_CLEAR);

return mask ? IRQ_HANDLED : IRQ_NONE;
}
Expand Down

0 comments on commit 8f90734

Please sign in to comment.