linux/drivers/dma
Lars-Peter Clausen 39ff86130a dma: pl330: Fix handling of TERMINATE_ALL while processing completed descriptors
The pl330 DMA driver is broken in regard to handling a terminate all request
while it is processing the list of completed descriptors. This is most visible
when calling dmaengine_terminate_all() from within the descriptors callback for
cyclic transfers. In this case the TERMINATE_ALL transfer will clear the
work_list and stop the transfer. But after all callbacks for all completed
descriptors have been handled the descriptors will be re-enqueued into the (now
empty) work_list. So the next time dma_async_issue_pending() is called for the
channel these descriptors will be transferred again which will cause data
corruption. Similar issues can occur if dmaengine_terminate_all() is not called
from within the descriptor callback but runs on a different CPU at the same time
as the completed descriptor list is processed.

This patch introduces a new per channel list which will hold the completed
descriptors. While processing the list the channel's lock will be held to avoid
racing against dmaengine_terminate_all(). The lock will be released when calling
the descriptors callback though. Since the list of completed descriptors might
be modified (e.g. by calling dmaengine_terminate_all() from the callback) we can
not use the normal list iterator macros. Instead we'll need to check for each
loop iteration again if there are still items in the list. The drivers
TERMINATE_ALL implementation is updated to move descriptors from both the
work_list as well the new completed_list back to the descriptor pool. This makes
sure that none of the descripts finds its way back into the work list and also
that we do not call any futher complete callbacks after
dmaengine_terminate_all() has been called.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
2013-08-28 11:27:17 +05:30
..
bestcomm Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc 2013-02-23 17:09:55 -08:00
dw dma: dw: return DMA_PAUSED only if cookie status is DMA_IN_PROGRESS 2013-08-05 09:32:26 +05:30
ioat drivers/dma: remove unused support for MEMSET operations 2013-07-03 16:07:42 -07:00
ipu dma: ipu: remove unnecessary platform_set_drvdata() 2013-08-25 14:37:13 +05:30
ppc4xx Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma 2013-07-07 11:11:43 -07:00
sh dma: use dev_get_platdata() 2013-08-13 16:56:41 +05:30
acpi-dma.c acpi-dma: remove ugly conversion 2013-08-25 16:43:45 +05:30
amba-pl08x.c dmaengine: PL08x: Avoid collisions with get_signal() macro 2013-07-05 11:40:47 +05:30
at_hdmac_regs.h DMA: AT91: Get residual bytes in dma buffer 2013-07-05 11:40:31 +05:30
at_hdmac.c dmaengine: at_hdmac: prepare clk before calling enable 2013-07-05 11:40:57 +05:30
coh901318_lli.c Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma 2013-02-26 09:24:48 -08:00
coh901318.c dma: coh901318: add devicetree support 2013-06-17 13:54:27 +02:00
coh901318.h dma: coh901318: merge header files 2013-01-07 17:36:37 +01:00
dma-jz4740.c MIPS: jz4740: Remove custom DMA API 2013-07-05 11:40:52 +05:30
dmaengine.c dmaengine: add interface of dma_get_slave_channel 2013-08-13 16:32:59 +05:30
dmaengine.h dmaengine: consolidate initialization of cookies 2012-03-13 11:37:22 +05:30
dmatest.c dmatest: do not allow to interrupt ongoing tests 2013-06-08 02:13:44 +05:30
edma.c edma: no need to assign residue to 0 explicitly 2013-08-05 09:32:24 +05:30
ep93xx_dma.c ep93xx_dma: remove useless use of lock 2013-08-05 09:32:24 +05:30
fsldma.c fsldma: remove useless use of lock 2013-08-05 09:32:24 +05:30
fsldma.h dmaengine: move last completed cookie into generic dma_chan structure 2012-03-13 11:36:06 +05:30
imx-dma.c DMA: imx-dma: imxdma->dev used uninitialized 2013-07-05 11:40:27 +05:30
imx-sdma.c dma: imx-sdma: Add ROM script addresses to driver 2013-08-26 20:47:16 +05:30
intel_mid_dma_regs.h dma: fix comments 2012-09-01 08:57:12 -07:00
intel_mid_dma.c PM / Runtime: Rework the "runtime idle" helper routine 2013-06-03 21:49:52 +02:00
iop-adma.c dma: use dev_get_platdata() 2013-08-13 16:56:41 +05:30
iovlock.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
k3dma.c dmaengine: Add hisilicon k3 DMA engine driver 2013-08-28 11:23:40 +05:30
Kconfig dmaengine: Add hisilicon k3 DMA engine driver 2013-08-28 11:23:40 +05:30
Makefile dmaengine: Add hisilicon k3 DMA engine driver 2013-08-28 11:23:40 +05:30
mmp_pdma.c dma: mmp_pdma: set DMA_PRIVATE 2013-08-25 22:04:53 +05:30
mmp_tdma.c dma: mmp: simplify use of devm_ioremap_resource 2013-08-14 14:51:28 +05:30
mpc512x_dma.c mpc512x_dma: remove useless use of lock 2013-08-05 09:32:25 +05:30
mv_xor.c dma: use dev_get_platdata() 2013-08-13 16:56:41 +05:30
mv_xor.h drivers/dma: remove unused support for MEMSET operations 2013-07-03 16:07:42 -07:00
mxs-dma.c dma: mxs-dma: remove code left from generic DMA binding conversion 2013-08-19 14:20:21 +05:30
of-dma.c dma: of: Remove check on always true condition 2013-06-12 07:49:19 +05:30
omap-dma.c dmaengine: OMAP: Register SDMA controller with Device Tree DMA driver 2013-04-15 09:51:19 +05:30
pch_dma.c pch_dma: remove useless use of lock 2013-08-05 09:32:25 +05:30
pl330.c dma: pl330: Fix handling of TERMINATE_ALL while processing completed descriptors 2013-08-28 11:27:17 +05:30
sa11x0-dma.c Drivers: dma: remove __dev* attributes. 2013-01-03 15:57:15 -08:00
sirf-dma.c dmaengine: sirf: add PM entries for sleep and runtime 2013-08-13 17:01:01 +05:30
ste_dma40_ll.c dmaengine: ste_dma40_ll: Replace meaningless register set with comment 2013-06-04 11:12:10 +02:00
ste_dma40_ll.h dmaengine: ste_dma40: Remove unnecessary call to d40_phy_cfg() 2013-05-23 21:13:19 +02:00
ste_dma40.c dmaengine: ste_dma40: off by one in d40_of_probe() 2013-08-25 16:23:32 +05:30
tegra20-apb-dma.c tegra20-apb-dma: remove useless use of lock 2013-08-05 09:32:25 +05:30
timb_dma.c dma: use dev_get_platdata() 2013-08-13 16:56:41 +05:30
TODO dmaengine: remove ste_dma40 from issue_pending TODO 2011-07-14 04:02:08 +05:30
txx9dmac.c dma: use dev_get_platdata() 2013-08-13 16:56:41 +05:30
txx9dmac.h dmaengine: move last completed cookie into generic dma_chan structure 2012-03-13 11:36:06 +05:30
virt-dma.c dmaengine: virt-dma: add support for cyclic DMA periodic callbacks 2012-07-01 14:15:23 +01:00
virt-dma.h dmaengine: virt-dma: add support for cyclic DMA periodic callbacks 2012-07-01 14:15:23 +01:00