diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2017-11-14 09:32:07 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2017-12-04 12:03:51 -0500 |
commit | de92436ac40ffe9933230aa503e24dbb5ede9201 (patch) | |
tree | d5899ce6b48f379c79b084edcd363c4ccbfe47a0 | |
parent | 174334bcd9f87286aead3b1a470a82348f9d43ec (diff) |
dmaengine: bcm2835-dma: Use vchan_terminate_vdesc() instead of desc_free
To avoid race with vchan_complete, use the race free way to terminate
running transfer.
Implement the device_synchronize callback to make sure that the terminated
descriptor is freed.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Acked-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r-- | drivers/dma/bcm2835-dma.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 6204cc32d09c..847f84a41a69 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c | |||
@@ -812,7 +812,7 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan) | |||
812 | * c->desc is NULL and exit.) | 812 | * c->desc is NULL and exit.) |
813 | */ | 813 | */ |
814 | if (c->desc) { | 814 | if (c->desc) { |
815 | bcm2835_dma_desc_free(&c->desc->vd); | 815 | vchan_terminate_vdesc(&c->desc->vd); |
816 | c->desc = NULL; | 816 | c->desc = NULL; |
817 | bcm2835_dma_abort(c->chan_base); | 817 | bcm2835_dma_abort(c->chan_base); |
818 | 818 | ||
@@ -836,6 +836,13 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan) | |||
836 | return 0; | 836 | return 0; |
837 | } | 837 | } |
838 | 838 | ||
839 | static void bcm2835_dma_synchronize(struct dma_chan *chan) | ||
840 | { | ||
841 | struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); | ||
842 | |||
843 | vchan_synchronize(&c->vc); | ||
844 | } | ||
845 | |||
839 | static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, | 846 | static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, |
840 | int irq, unsigned int irq_flags) | 847 | int irq, unsigned int irq_flags) |
841 | { | 848 | { |
@@ -942,6 +949,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) | |||
942 | od->ddev.device_prep_dma_memcpy = bcm2835_dma_prep_dma_memcpy; | 949 | od->ddev.device_prep_dma_memcpy = bcm2835_dma_prep_dma_memcpy; |
943 | od->ddev.device_config = bcm2835_dma_slave_config; | 950 | od->ddev.device_config = bcm2835_dma_slave_config; |
944 | od->ddev.device_terminate_all = bcm2835_dma_terminate_all; | 951 | od->ddev.device_terminate_all = bcm2835_dma_terminate_all; |
952 | od->ddev.device_synchronize = bcm2835_dma_synchronize; | ||
945 | od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); | 953 | od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); |
946 | od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); | 954 | od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); |
947 | od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | | 955 | od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | |