|
@@ -295,6 +295,39 @@ static inline struct pl08x_txd *to_pl08x_txd(struct dma_async_tx_descriptor *tx)
|
|
|
return container_of(tx, struct pl08x_txd, 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;
|
|
|
}
|