diff options
author | Vinod Koul <vinod.koul@intel.com> | 2016-01-06 04:47:47 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2016-01-06 04:47:47 -0500 |
commit | d3f1e93ce8e00be19711c35f0c67c54a58aea559 (patch) | |
tree | 58010cdfa4fc473fc0693410b4a444755c4438c9 /drivers | |
parent | 7c7b680fa6b0866af2c4876da261bbfe710315d6 (diff) | |
parent | b1d6ab1aa8cdc23b89bcd578ea8d5e3c501a13d9 (diff) |
Merge branch 'topic/async' into for-linus
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dma/dma-axi-dmac.c | 8 | ||||
-rw-r--r-- | drivers/dma/dmaengine.c | 5 | ||||
-rw-r--r-- | drivers/dma/virt-dma.h | 13 |
3 files changed, 25 insertions, 1 deletions
diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index 5b2395e7e04d..c3468094393e 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c | |||
@@ -307,6 +307,13 @@ static int axi_dmac_terminate_all(struct dma_chan *c) | |||
307 | return 0; | 307 | return 0; |
308 | } | 308 | } |
309 | 309 | ||
310 | static void axi_dmac_synchronize(struct dma_chan *c) | ||
311 | { | ||
312 | struct axi_dmac_chan *chan = to_axi_dmac_chan(c); | ||
313 | |||
314 | vchan_synchronize(&chan->vchan); | ||
315 | } | ||
316 | |||
310 | static void axi_dmac_issue_pending(struct dma_chan *c) | 317 | static void axi_dmac_issue_pending(struct dma_chan *c) |
311 | { | 318 | { |
312 | struct axi_dmac_chan *chan = to_axi_dmac_chan(c); | 319 | struct axi_dmac_chan *chan = to_axi_dmac_chan(c); |
@@ -613,6 +620,7 @@ static int axi_dmac_probe(struct platform_device *pdev) | |||
613 | dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; | 620 | dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; |
614 | dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; | 621 | dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; |
615 | dma_dev->device_terminate_all = axi_dmac_terminate_all; | 622 | dma_dev->device_terminate_all = axi_dmac_terminate_all; |
623 | dma_dev->device_synchronize = axi_dmac_synchronize; | ||
616 | dma_dev->dev = &pdev->dev; | 624 | dma_dev->dev = &pdev->dev; |
617 | dma_dev->chancnt = 1; | 625 | dma_dev->chancnt = 1; |
618 | dma_dev->src_addr_widths = BIT(dmac->chan.src_width); | 626 | dma_dev->src_addr_widths = BIT(dmac->chan.src_width); |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 21c8c0bce3af..c50a247be2e0 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -266,8 +266,11 @@ static void dma_chan_put(struct dma_chan *chan) | |||
266 | module_put(dma_chan_to_owner(chan)); | 266 | module_put(dma_chan_to_owner(chan)); |
267 | 267 | ||
268 | /* This channel is not in use anymore, free it */ | 268 | /* This channel is not in use anymore, free it */ |
269 | if (!chan->client_count && chan->device->device_free_chan_resources) | 269 | if (!chan->client_count && chan->device->device_free_chan_resources) { |
270 | /* Make sure all operations have completed */ | ||
271 | dmaengine_synchronize(chan); | ||
270 | chan->device->device_free_chan_resources(chan); | 272 | chan->device->device_free_chan_resources(chan); |
273 | } | ||
271 | 274 | ||
272 | /* If the channel is used via a DMA request router, free the mapping */ | 275 | /* If the channel is used via a DMA request router, free the mapping */ |
273 | if (chan->router && chan->router->route_free) { | 276 | if (chan->router && chan->router->route_free) { |
diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h index bff8c39dd716..d9731ca5e262 100644 --- a/drivers/dma/virt-dma.h +++ b/drivers/dma/virt-dma.h | |||
@@ -163,4 +163,17 @@ static inline void vchan_free_chan_resources(struct virt_dma_chan *vc) | |||
163 | vchan_dma_desc_free_list(vc, &head); | 163 | vchan_dma_desc_free_list(vc, &head); |
164 | } | 164 | } |
165 | 165 | ||
166 | /** | ||
167 | * vchan_synchronize() - synchronize callback execution to the current context | ||
168 | * @vc: virtual channel to synchronize | ||
169 | * | ||
170 | * Makes sure that all scheduled or active callbacks have finished running. For | ||
171 | * proper operation the caller has to ensure that no new callbacks are scheduled | ||
172 | * after the invocation of this function started. | ||
173 | */ | ||
174 | static inline void vchan_synchronize(struct virt_dma_chan *vc) | ||
175 | { | ||
176 | tasklet_kill(&vc->task); | ||
177 | } | ||
178 | |||
166 | #endif | 179 | #endif |