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 |
