dmaengine: PL08x: move DMA signal muxing into pl08x_dma_chan struct

Move the signal handling out of the physical channel structure into
the virtual channel structure, where it should belong as it has more
to do with the virtual channel than the physical one.

Acked-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Russell King 2012-05-25 11:15:15 +01:00
parent 6b16c8b161
commit ad0de2ac32

View file

@ -136,17 +136,17 @@ struct pl08x_bus_data {
* struct pl08x_phy_chan - holder for the physical channels * struct pl08x_phy_chan - holder for the physical channels
* @id: physical index to this channel * @id: physical index to this channel
* @lock: a lock to use when altering an instance of this struct * @lock: a lock to use when altering an instance of this struct
* @signal: the physical signal (aka channel) serving this physical channel
* right now
* @serving: the virtual channel currently being served by this physical * @serving: the virtual channel currently being served by this physical
* channel * channel
* @locked: channel unavailable for the system, e.g. dedicated to secure
* world
*/ */
struct pl08x_phy_chan { struct pl08x_phy_chan {
unsigned int id; unsigned int id;
void __iomem *base; void __iomem *base;
spinlock_t lock; spinlock_t lock;
int signal;
struct pl08x_dma_chan *serving; struct pl08x_dma_chan *serving;
bool locked;
}; };
/** /**
@ -226,6 +226,7 @@ enum pl08x_dma_chan_state {
* @slave: whether this channel is a device (slave) or for memcpy * @slave: whether this channel is a device (slave) or for memcpy
* @waiting: a TX descriptor on this channel which is waiting for a physical * @waiting: a TX descriptor on this channel which is waiting for a physical
* channel to become available * channel to become available
* @signal: the physical DMA request signal which this channel is using
*/ */
struct pl08x_dma_chan { struct pl08x_dma_chan {
struct dma_chan chan; struct dma_chan chan;
@ -242,6 +243,7 @@ struct pl08x_dma_chan {
enum pl08x_dma_chan_state state; enum pl08x_dma_chan_state state;
bool slave; bool slave;
struct pl08x_txd *waiting; struct pl08x_txd *waiting;
int signal;
}; };
/** /**
@ -303,7 +305,7 @@ static inline struct pl08x_txd *to_pl08x_txd(struct dma_async_tx_descriptor *tx)
* via a board/SoC specific external MUX. One important point to note * via a board/SoC specific external MUX. One important point to note
* here is that this does not depend on the physical channel. * here is that this does not depend on the physical channel.
*/ */
static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct pl08x_phy_chan *ch) static int pl08x_request_mux(struct pl08x_dma_chan *plchan)
{ {
const struct pl08x_platform_data *pd = plchan->host->pd; const struct pl08x_platform_data *pd = plchan->host->pd;
int ret; int ret;
@ -313,7 +315,7 @@ static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct pl08x_phy_cha
if (ret < 0) if (ret < 0)
return ret; return ret;
ch->signal = ret; plchan->signal = ret;
} }
return 0; return 0;
} }
@ -322,9 +324,9 @@ static void pl08x_release_mux(struct pl08x_dma_chan *plchan)
{ {
const struct pl08x_platform_data *pd = plchan->host->pd; const struct pl08x_platform_data *pd = plchan->host->pd;
if (plchan->phychan->signal >= 0 && pd->put_signal) { if (plchan->signal >= 0 && pd->put_signal) {
pd->put_signal(plchan->cd, plchan->phychan->signal); pd->put_signal(plchan->cd, plchan->signal);
plchan->phychan->signal = -1; plchan->signal = -1;
} }
} }
@ -549,7 +551,6 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
if (!ch->locked && !ch->serving) { if (!ch->locked && !ch->serving) {
ch->serving = virt_chan; ch->serving = virt_chan;
ch->signal = -1;
spin_unlock_irqrestore(&ch->lock, flags); spin_unlock_irqrestore(&ch->lock, flags);
break; break;
} }
@ -1033,7 +1034,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
* Can the platform allow us to use this channel? * Can the platform allow us to use this channel?
*/ */
if (plchan->slave) { if (plchan->slave) {
ret = pl08x_request_mux(plchan, ch); ret = pl08x_request_mux(plchan);
if (ret < 0) { if (ret < 0) {
dev_dbg(&pl08x->adev->dev, dev_dbg(&pl08x->adev->dev,
"unable to use physical channel %d for transfer on %s due to platform restrictions\n", "unable to use physical channel %d for transfer on %s due to platform restrictions\n",
@ -1047,15 +1048,15 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
plchan->phychan = ch; plchan->phychan = ch;
dev_dbg(&pl08x->adev->dev, "allocated physical channel %d and signal %d for xfer on %s\n", dev_dbg(&pl08x->adev->dev, "allocated physical channel %d and signal %d for xfer on %s\n",
ch->id, ch->id,
ch->signal, plchan->signal,
plchan->name); plchan->name);
got_channel: got_channel:
/* Assign the flow control signal to this channel */ /* Assign the flow control signal to this channel */
if (txd->direction == DMA_MEM_TO_DEV) if (txd->direction == DMA_MEM_TO_DEV)
txd->ccfg |= ch->signal << PL080_CONFIG_DST_SEL_SHIFT; txd->ccfg |= plchan->signal << PL080_CONFIG_DST_SEL_SHIFT;
else if (txd->direction == DMA_DEV_TO_MEM) else if (txd->direction == DMA_DEV_TO_MEM)
txd->ccfg |= ch->signal << PL080_CONFIG_SRC_SEL_SHIFT; txd->ccfg |= plchan->signal << PL080_CONFIG_SRC_SEL_SHIFT;
plchan->phychan_hold++; plchan->phychan_hold++;
@ -1825,6 +1826,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
chan->host = pl08x; chan->host = pl08x;
chan->state = PL08X_CHAN_IDLE; chan->state = PL08X_CHAN_IDLE;
chan->signal = -1;
if (slave) { if (slave) {
chan->cd = &pl08x->pd->slave_channels[i]; chan->cd = &pl08x->pd->slave_channels[i];
@ -2062,7 +2064,6 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
ch->id = i; ch->id = i;
ch->base = pl08x->base + PL080_Cx_BASE(i); ch->base = pl08x->base + PL080_Cx_BASE(i);
spin_lock_init(&ch->lock); spin_lock_init(&ch->lock);
ch->signal = -1;
/* /*
* Nomadik variants can have channels that are locked * Nomadik variants can have channels that are locked