aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/amba-pl08x.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index b579bac56383..c203d2f22bca 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -136,17 +136,17 @@ struct pl08x_bus_data {
136 * struct pl08x_phy_chan - holder for the physical channels 136 * struct pl08x_phy_chan - holder for the physical channels
137 * @id: physical index to this channel 137 * @id: physical index to this channel
138 * @lock: a lock to use when altering an instance of this struct 138 * @lock: a lock to use when altering an instance of this struct
139 * @signal: the physical signal (aka channel) serving this physical channel
140 * right now
141 * @serving: the virtual channel currently being served by this physical 139 * @serving: the virtual channel currently being served by this physical
142 * channel 140 * channel
141 * @locked: channel unavailable for the system, e.g. dedicated to secure
142 * world
143 */ 143 */
144struct pl08x_phy_chan { 144struct pl08x_phy_chan {
145 unsigned int id; 145 unsigned int id;
146 void __iomem *base; 146 void __iomem *base;
147 spinlock_t lock; 147 spinlock_t lock;
148 int signal;
149 struct pl08x_dma_chan *serving; 148 struct pl08x_dma_chan *serving;
149 bool locked;
150}; 150};
151 151
152/** 152/**
@@ -226,6 +226,7 @@ enum pl08x_dma_chan_state {
226 * @slave: whether this channel is a device (slave) or for memcpy 226 * @slave: whether this channel is a device (slave) or for memcpy
227 * @waiting: a TX descriptor on this channel which is waiting for a physical 227 * @waiting: a TX descriptor on this channel which is waiting for a physical
228 * channel to become available 228 * channel to become available
229 * @signal: the physical DMA request signal which this channel is using
229 */ 230 */
230struct pl08x_dma_chan { 231struct pl08x_dma_chan {
231 struct dma_chan chan; 232 struct dma_chan chan;
@@ -242,6 +243,7 @@ struct pl08x_dma_chan {
242 enum pl08x_dma_chan_state state; 243 enum pl08x_dma_chan_state state;
243 bool slave; 244 bool slave;
244 struct pl08x_txd *waiting; 245 struct pl08x_txd *waiting;
246 int signal;
245}; 247};
246 248
247/** 249/**
@@ -303,7 +305,7 @@ static inline struct pl08x_txd *to_pl08x_txd(struct dma_async_tx_descriptor *tx)
303 * via a board/SoC specific external MUX. One important point to note 305 * via a board/SoC specific external MUX. One important point to note
304 * here is that this does not depend on the physical channel. 306 * here is that this does not depend on the physical channel.
305 */ 307 */
306static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct pl08x_phy_chan *ch) 308static int pl08x_request_mux(struct pl08x_dma_chan *plchan)
307{ 309{
308 const struct pl08x_platform_data *pd = plchan->host->pd; 310 const struct pl08x_platform_data *pd = plchan->host->pd;
309 int ret; 311 int ret;
@@ -313,7 +315,7 @@ static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct pl08x_phy_cha
313 if (ret < 0) 315 if (ret < 0)
314 return ret; 316 return ret;
315 317
316 ch->signal = ret; 318 plchan->signal = ret;
317 } 319 }
318 return 0; 320 return 0;
319} 321}
@@ -322,9 +324,9 @@ static void pl08x_release_mux(struct pl08x_dma_chan *plchan)
322{ 324{
323 const struct pl08x_platform_data *pd = plchan->host->pd; 325 const struct pl08x_platform_data *pd = plchan->host->pd;
324 326
325 if (plchan->phychan->signal >= 0 && pd->put_signal) { 327 if (plchan->signal >= 0 && pd->put_signal) {
326 pd->put_signal(plchan->cd, plchan->phychan->signal); 328 pd->put_signal(plchan->cd, plchan->signal);
327 plchan->phychan->signal = -1; 329 plchan->signal = -1;
328 } 330 }
329} 331}
330 332
@@ -549,7 +551,6 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
549 551
550 if (!ch->locked && !ch->serving) { 552 if (!ch->locked && !ch->serving) {
551 ch->serving = virt_chan; 553 ch->serving = virt_chan;
552 ch->signal = -1;
553 spin_unlock_irqrestore(&ch->lock, flags); 554 spin_unlock_irqrestore(&ch->lock, flags);
554 break; 555 break;
555 } 556 }
@@ -1033,7 +1034,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
1033 * Can the platform allow us to use this channel? 1034 * Can the platform allow us to use this channel?
1034 */ 1035 */
1035 if (plchan->slave) { 1036 if (plchan->slave) {
1036 ret = pl08x_request_mux(plchan, ch); 1037 ret = pl08x_request_mux(plchan);
1037 if (ret < 0) { 1038 if (ret < 0) {
1038 dev_dbg(&pl08x->adev->dev, 1039 dev_dbg(&pl08x->adev->dev,
1039 "unable to use physical channel %d for transfer on %s due to platform restrictions\n", 1040 "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,
1047 plchan->phychan = ch; 1048 plchan->phychan = ch;
1048 dev_dbg(&pl08x->adev->dev, "allocated physical channel %d and signal %d for xfer on %s\n", 1049 dev_dbg(&pl08x->adev->dev, "allocated physical channel %d and signal %d for xfer on %s\n",
1049 ch->id, 1050 ch->id,
1050 ch->signal, 1051 plchan->signal,
1051 plchan->name); 1052 plchan->name);
1052 1053
1053got_channel: 1054got_channel:
1054 /* Assign the flow control signal to this channel */ 1055 /* Assign the flow control signal to this channel */
1055 if (txd->direction == DMA_MEM_TO_DEV) 1056 if (txd->direction == DMA_MEM_TO_DEV)
1056 txd->ccfg |= ch->signal << PL080_CONFIG_DST_SEL_SHIFT; 1057 txd->ccfg |= plchan->signal << PL080_CONFIG_DST_SEL_SHIFT;
1057 else if (txd->direction == DMA_DEV_TO_MEM) 1058 else if (txd->direction == DMA_DEV_TO_MEM)
1058 txd->ccfg |= ch->signal << PL080_CONFIG_SRC_SEL_SHIFT; 1059 txd->ccfg |= plchan->signal << PL080_CONFIG_SRC_SEL_SHIFT;
1059 1060
1060 plchan->phychan_hold++; 1061 plchan->phychan_hold++;
1061 1062
@@ -1825,6 +1826,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1825 1826
1826 chan->host = pl08x; 1827 chan->host = pl08x;
1827 chan->state = PL08X_CHAN_IDLE; 1828 chan->state = PL08X_CHAN_IDLE;
1829 chan->signal = -1;
1828 1830
1829 if (slave) { 1831 if (slave) {
1830 chan->cd = &pl08x->pd->slave_channels[i]; 1832 chan->cd = &pl08x->pd->slave_channels[i];
@@ -2062,7 +2064,6 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
2062 ch->id = i; 2064 ch->id = i;
2063 ch->base = pl08x->base + PL080_Cx_BASE(i); 2065 ch->base = pl08x->base + PL080_Cx_BASE(i);
2064 spin_lock_init(&ch->lock); 2066 spin_lock_init(&ch->lock);
2065 ch->signal = -1;
2066 2067
2067 /* 2068 /*
2068 * Nomadik variants can have channels that are locked 2069 * Nomadik variants can have channels that are locked