diff options
-rw-r--r-- | drivers/dma/amba-pl08x.c | 29 |
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 | */ |
144 | struct pl08x_phy_chan { | 144 | struct 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 | */ |
230 | struct pl08x_dma_chan { | 231 | struct 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 | */ |
306 | static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct pl08x_phy_chan *ch) | 308 | static 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 | ||
1053 | got_channel: | 1054 | got_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 |