aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/amba-pl08x.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index f7397789e4e8..b579bac56383 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)
296} 296}
297 297
298/* 298/*
299 * Mux handling.
300 *
301 * This gives us the DMA request input to the PL08x primecell which the
302 * peripheral described by the channel data will be routed to, possibly
303 * via a board/SoC specific external MUX. One important point to note
304 * here is that this does not depend on the physical channel.
305 */
306static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct pl08x_phy_chan *ch)
307{
308 const struct pl08x_platform_data *pd = plchan->host->pd;
309 int ret;
310
311 if (pd->get_signal) {
312 ret = pd->get_signal(plchan->cd);
313 if (ret < 0)
314 return ret;
315
316 ch->signal = ret;
317 }
318 return 0;
319}
320
321static void pl08x_release_mux(struct pl08x_dma_chan *plchan)
322{
323 const struct pl08x_platform_data *pd = plchan->host->pd;
324
325 if (plchan->phychan->signal >= 0 && pd->put_signal) {
326 pd->put_signal(plchan->cd, plchan->phychan->signal);
327 plchan->phychan->signal = -1;
328 }
329}
330
331/*
299 * Physical channel handling 332 * Physical channel handling
300 */ 333 */
301 334
@@ -999,8 +1032,8 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
999 * need, but for slaves the physical signals may be muxed! 1032 * need, but for slaves the physical signals may be muxed!
1000 * Can the platform allow us to use this channel? 1033 * Can the platform allow us to use this channel?
1001 */ 1034 */
1002 if (plchan->slave && pl08x->pd->get_signal) { 1035 if (plchan->slave) {
1003 ret = pl08x->pd->get_signal(plchan->cd); 1036 ret = pl08x_request_mux(plchan, ch);
1004 if (ret < 0) { 1037 if (ret < 0) {
1005 dev_dbg(&pl08x->adev->dev, 1038 dev_dbg(&pl08x->adev->dev,
1006 "unable to use physical channel %d for transfer on %s due to platform restrictions\n", 1039 "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,
1009 pl08x_put_phy_channel(pl08x, ch); 1042 pl08x_put_phy_channel(pl08x, ch);
1010 return -EBUSY; 1043 return -EBUSY;
1011 } 1044 }
1012 ch->signal = ret;
1013 } 1045 }
1014 1046
1015 plchan->phychan = ch; 1047 plchan->phychan = ch;
@@ -1034,10 +1066,7 @@ static void release_phy_channel(struct pl08x_dma_chan *plchan)
1034{ 1066{
1035 struct pl08x_driver_data *pl08x = plchan->host; 1067 struct pl08x_driver_data *pl08x = plchan->host;
1036 1068
1037 if ((plchan->phychan->signal >= 0) && pl08x->pd->put_signal) { 1069 pl08x_release_mux(plchan);
1038 pl08x->pd->put_signal(plchan->cd, plchan->phychan->signal);
1039 plchan->phychan->signal = -1;
1040 }
1041 pl08x_put_phy_channel(pl08x, plchan->phychan); 1070 pl08x_put_phy_channel(pl08x, plchan->phychan);
1042 plchan->phychan = NULL; 1071 plchan->phychan = NULL;
1043} 1072}