Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 321152
b: refs/heads/master
c: a936e79
h: refs/heads/master
v: v3
  • Loading branch information
Russell King committed Jul 1, 2012
1 parent aa8baef commit 12bf5fa
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 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: 5e2479bd0e0dc41f2b9f6b4345bc5d4557837056
refs/heads/master: a936e793136b4238ef287cfbbdd25ebb78214529
30 changes: 20 additions & 10 deletions trunk/drivers/dma/amba-pl08x.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ enum pl08x_dma_chan_state {
* @cd: channel platform data
* @runtime_addr: address for RX/TX according to the runtime config
* @pend_list: queued transactions pending on this channel
* @done_list: list of completed transactions
* @at: active transaction on this channel
* @lock: a lock for this channel data
* @host: a pointer to the host (internal use)
Expand All @@ -238,6 +239,7 @@ struct pl08x_dma_chan {
const struct pl08x_channel_data *cd;
struct dma_slave_config cfg;
struct list_head pend_list;
struct list_head done_list;
struct pl08x_txd *at;
spinlock_t lock;
struct pl08x_driver_data *host;
Expand Down Expand Up @@ -1673,18 +1675,11 @@ static void pl08x_tasklet(unsigned long data)
{
struct pl08x_dma_chan *plchan = (struct pl08x_dma_chan *) data;
struct pl08x_driver_data *pl08x = plchan->host;
struct pl08x_txd *txd;
unsigned long flags;
LIST_HEAD(head);

spin_lock_irqsave(&plchan->lock, flags);

txd = plchan->at;
plchan->at = NULL;

if (txd) {
/* Update last completed */
dma_cookie_complete(&txd->tx);
}
list_splice_tail_init(&plchan->done_list, &head);

/* If a new descriptor is queued, set it up plchan->at is NULL here */
if (!list_empty(&plchan->pend_list)) {
Expand Down Expand Up @@ -1739,10 +1734,14 @@ static void pl08x_tasklet(unsigned long data)

spin_unlock_irqrestore(&plchan->lock, flags);

if (txd) {
while (!list_empty(&head)) {
struct pl08x_txd *txd = list_first_entry(&head,
struct pl08x_txd, node);
dma_async_tx_callback callback = txd->tx.callback;
void *callback_param = txd->tx.callback_param;

list_del(&txd->node);

/* Don't try to unmap buffers on slave channels */
if (!plchan->slave)
pl08x_unmap_buffers(txd);
Expand Down Expand Up @@ -1782,6 +1781,7 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
/* Locate physical channel */
struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i];
struct pl08x_dma_chan *plchan = phychan->serving;
struct pl08x_txd *tx;

if (!plchan) {
dev_err(&pl08x->adev->dev,
Expand All @@ -1790,6 +1790,15 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
continue;
}

spin_lock(&plchan->lock);
tx = plchan->at;
if (tx) {
plchan->at = NULL;
dma_cookie_complete(&tx->tx);
list_add_tail(&tx->node, &plchan->done_list);
}
spin_unlock(&plchan->lock);

/* Schedule tasklet on this channel */
tasklet_schedule(&plchan->tasklet);
mask |= (1 << i);
Expand Down Expand Up @@ -1856,6 +1865,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,

spin_lock_init(&chan->lock);
INIT_LIST_HEAD(&chan->pend_list);
INIT_LIST_HEAD(&chan->done_list);
tasklet_init(&chan->tasklet, pl08x_tasklet,
(unsigned long) chan);

Expand Down

0 comments on commit 12bf5fa

Please sign in to comment.