Skip to content

Commit

Permalink
ARM: PL08x: introduce 'phychan_hold' to hold on to physical channels
Browse files Browse the repository at this point in the history
Introduce 'phychan_hold' to hold on to physical DMA channels while we're
preparing a new descriptor for it.  This will be incremented when we
allocate a physical channel and set the MUX registers during the
preparation of the TXD, and will only be decremented when the TXD is
submitted.

This prevents the physical channel being given up before the new TXD
is placed on the queue.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Russell King - ARM Linux authored and Dan Williams committed Jan 5, 2011
1 parent 501e67e commit 8087aac
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/dma/amba-pl08x.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
ch->signal,
plchan->name);

plchan->phychan_hold++;
plchan->phychan = ch;

return 0;
Expand Down Expand Up @@ -998,6 +999,8 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
/* Do this memcpy whenever there is a channel ready */
plchan->state = PL08X_CHAN_WAITING;
plchan->waiting = txd;
} else {
plchan->phychan_hold--;
}

/* This unlock follows the lock in the prep() function */
Expand Down Expand Up @@ -1585,6 +1588,7 @@ static void pl08x_tasklet(unsigned long data)
*/
plchan->lc = txd->tx.cookie;
}

/*
* If a new descriptor is queued, set it up
* plchan->at is NULL here
Expand All @@ -1598,6 +1602,12 @@ static void pl08x_tasklet(unsigned long data)
list_del(&next->node);

pl08x_start_txd(plchan, next);
} else if (plchan->phychan_hold) {
/*
* This channel is still in use - we have a new txd being
* prepared and will soon be queued. Don't give up the
* physical channel.
*/
} else {
struct pl08x_dma_chan *waiting = NULL;

Expand Down Expand Up @@ -1625,6 +1635,7 @@ static void pl08x_tasklet(unsigned long data)
ret = prep_phy_channel(waiting,
waiting->waiting);
BUG_ON(ret);
waiting->phychan_hold--;
waiting->state = PL08X_CHAN_RUNNING;
waiting->waiting = NULL;
pl08x_issue_pending(&waiting->chan);
Expand Down
3 changes: 3 additions & 0 deletions include/linux/amba/pl08x.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ enum pl08x_dma_chan_state {
* struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
* @chan: wrappped abstract channel
* @phychan: the physical channel utilized by this channel, if there is one
* @phychan_hold: if non-zero, hold on to the physical channel even if we
* have no pending entries
* @tasklet: tasklet scheduled by the IRQ to handle actual work etc
* @name: name of channel
* @cd: channel platform data
Expand All @@ -173,6 +175,7 @@ enum pl08x_dma_chan_state {
struct pl08x_dma_chan {
struct dma_chan chan;
struct pl08x_phy_chan *phychan;
int phychan_hold;
struct tasklet_struct tasklet;
char *name;
struct pl08x_channel_data *cd;
Expand Down

0 comments on commit 8087aac

Please sign in to comment.