diff options
Diffstat (limited to 'drivers')
-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 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 | */ | ||
306 | static 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 | |||
321 | static 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 | } |