diff options
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r-- | drivers/dma/amba-pl08x.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index f739778..b579bac 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -296,6 +296,39 @@ static inline struct pl08x_txd *to_pl08x_txd(struct dma_async_tx_descriptor *tx) } /* + * Mux handling. + * + * This gives us the DMA request input to the PL08x primecell which the + * peripheral described by the channel data will be routed to, possibly + * via a board/SoC specific external MUX. One important point to note + * 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) +{ + const struct pl08x_platform_data *pd = plchan->host->pd; + int ret; + + if (pd->get_signal) { + ret = pd->get_signal(plchan->cd); + if (ret < 0) + return ret; + + ch->signal = ret; + } + return 0; +} + +static void pl08x_release_mux(struct pl08x_dma_chan *plchan) +{ + const struct pl08x_platform_data *pd = plchan->host->pd; + + if (plchan->phychan->signal >= 0 && pd->put_signal) { + pd->put_signal(plchan->cd, plchan->phychan->signal); + plchan->phychan->signal = -1; + } +} + +/* * Physical channel handling */ @@ -999,8 +1032,8 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan, * need, but for slaves the physical signals may be muxed! * Can the platform allow us to use this channel? */ - if (plchan->slave && pl08x->pd->get_signal) { - ret = pl08x->pd->get_signal(plchan->cd); + if (plchan->slave) { + ret = pl08x_request_mux(plchan, ch); if (ret < 0) { dev_dbg(&pl08x->adev->dev, "unable to use physical channel %d for transfer on %s due to platform restrictions\n", @@ -1009,7 +1042,6 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan, pl08x_put_phy_channel(pl08x, ch); return -EBUSY; } - ch->signal = ret; } plchan->phychan = ch; @@ -1034,10 +1066,7 @@ static void release_phy_channel(struct pl08x_dma_chan *plchan) { struct pl08x_driver_data *pl08x = plchan->host; - if ((plchan->phychan->signal >= 0) && pl08x->pd->put_signal) { - pl08x->pd->put_signal(plchan->cd, plchan->phychan->signal); - plchan->phychan->signal = -1; - } + pl08x_release_mux(plchan); pl08x_put_phy_channel(pl08x, plchan->phychan); plchan->phychan = NULL; } |