linux/drivers/dma
Tony Lindgren 362f456246 dmaengine: cppi41: Fix oops in cppi41_runtime_resume
Commit fdea2d09b9 ("dmaengine: cppi41: Add basic PM runtime support")
together with recent MUSB changes allowed USB and DMA on BeagleBone to idle
when no cable is connected. But looks like few corner case issues still
remain.

Looks like just by re-plugging USB cable about ten or so times on BeagleBone
when configured in USB peripheral mode we can get warnings and eventually
trigger an oops in cppi41 DMA:

WARNING: CPU: 0 PID: 14 at drivers/dma/cppi41.c:1154 cppi41_runtime_suspend+
x28/0x38 [cppi41]
...

WARNING: CPU: 0 PID: 14 at drivers/dma/cppi41.c:452
push_desc_queue+0x94/0x9c [cppi41]
...

Unable to handle kernel NULL pointer dereference at virtual
address 00000104
pgd = c0004000
[00000104] *pgd=00000000
Internal error: Oops: 805 [#1] SMP ARM
...
[<bf0d92cc>] (cppi41_runtime_resume [cppi41]) from [<c0589838>]
(__rpm_callback+0xc0/0x214)
[<c0589838>] (__rpm_callback) from [<c05899ac>] (rpm_callback+0x20/0x80)
[<c05899ac>] (rpm_callback) from [<c0589460>] (rpm_resume+0x504/0x78c)
[<c0589460>] (rpm_resume) from [<c058a1a0>] (pm_runtime_work+0x60/0xa8)
[<c058a1a0>] (pm_runtime_work) from [<c0156120>] (process_one_work+0x2b4/0x808)

This is because of a race with runtime PM and cppi41_dma_issue_pending()
as reported by Alexandre Bailon <abailon@baylibre.com> in earlier
set of patches. Based on mailing list discussions we however came to the
conclusion that a different fix from Alexandre's fix is needed in order
to guarantee that DMA is really active when we try to use it.

To fix the issue, we need to add a driver specific flag as we otherwise
can have -EINPROGRESS state set by runtime PM and can't rely on
pm_runtime_active() to tell us when we can use the DMA.

And we need to make sure the DMA transfers get triggered in the queued
order. So let's always queue the transfers, then flush the queue
from both cppi41_dma_issue_pending() and cppi41_runtime_resume()
as suggested by Grygorii Strashko <grygorii.strashko@ti.com> in an
earlier example patch.

For reference, this is also documented in Documentation/power/runtime_pm.txt
in the example at the end of the file as pointed out by Grygorii Strashko
<grygorii.strashko@ti.com>.

Based on earlier patches from Alexandre Bailon <abailon@baylibre.com>
and Grygorii Strashko <grygorii.strashko@ti.com> modified based on
testing and what was discussed on the mailing lists.

Fixes: fdea2d09b9 ("dmaengine: cppi41: Add basic PM runtime support")
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Bin Liu <b-liu@ti.com>
Cc: Grygorii Strashko <grygorii.strashko@ti.com>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Patrick Titiano <ptitiano@baylibre.com>
Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reported-by: Alexandre Bailon <abailon@baylibre.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Tested-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
2017-01-25 11:29:22 +05:30
..
bestcomm dmaengine: NO_IRQ removal from powerpc-only drivers 2016-09-14 18:57:38 +05:30
dw dmaengine: dw: fix typo in Kconfig 2017-01-02 08:13:00 +05:30
hsu dmaengine: hsu: pci: switch to new API for IRQ allocation 2016-11-25 11:11:08 +05:30
ioat dmaengine: iota: ioat_alloc_chan_resources should not perform sleeping allocations. 2017-01-10 10:41:51 +05:30
ipu Merge branch 'topic/no_irq' into for-linus 2016-10-03 09:18:29 +05:30
ppc4xx Merge branch 'topic/unmap_cleanup' into for-linus 2016-10-03 09:36:11 +05:30
qcom dmaengine: qcom_hidma: autoload while probing ACPI 2016-11-23 09:47:32 +05:30
sh dmaengine: rcar-dmac: unmap slave resource when channel is freed 2017-01-13 12:14:28 +05:30
xilinx dmengine: xilinx_dma: convert callback to helper function 2016-08-08 08:11:43 +05:30
acpi-dma.c
amba-pl08x.c dmaengine: pl08x: Add support for the DMA slave map 2016-11-17 15:51:28 +05:30
at_hdmac_regs.h
at_hdmac.c dmaengine: at_hdmac: move to dma_pool_zalloc 2016-12-08 21:24:17 +05:30
at_xdmac.c dmaengine: at_xdmac: don't restore unsaved status 2016-12-06 10:45:48 +05:30
bcm2835-dma.c dmaengine: bcm2835: fix 64-bit warning 2016-07-06 22:39:43 +05:30
coh901318_lli.c dmaengine: coh901318: use NULL for pointer initialization 2016-09-26 22:28:24 +05:30
coh901318.c Merge branch 'topic/err_reporting' into for-linus 2016-10-03 09:17:33 +05:30
coh901318.h
cppi41.c dmaengine: cppi41: Fix oops in cppi41_runtime_resume 2017-01-25 11:29:22 +05:30
dma-axi-dmac.c dmaengine: axi-dmac: Return IRQ_NONE if no IRQs are pending 2016-07-01 22:56:41 +05:30
dma-jz4740.c dmaengine: jz4740: remove unused arch header 2016-09-26 22:25:57 +05:30
dma-jz4780.c Merge branch 'topic/compile_test' into for-linus 2016-10-03 09:16:03 +05:30
dmaengine.c dmaengine: device must have at least one channel 2016-08-22 11:49:07 +05:30
dmaengine.h dmaengine: add support to provide error result from a DMA transation 2016-08-08 08:11:42 +05:30
dmatest.c ktime: Cleanup ktime_set() usage 2016-12-25 17:21:22 +01:00
edma.c dmaengine updates for 4.10-rc1 2016-12-14 20:42:45 -08:00
ep93xx_dma.c Merge branch 'topic/err_reporting' into for-linus 2016-10-03 09:17:33 +05:30
fsl_raid.c dmaengine: fsl_raid: Fix module autoload 2016-11-14 08:35:13 +05:30
fsl_raid.h
fsl-edma.c dmaengine: fsl-edma: kill the tasklets upon exit 2016-07-16 20:19:00 +05:30
fsldma.c Merge branch 'topic/unmap_cleanup' into for-linus 2016-10-03 09:36:11 +05:30
fsldma.h
idma64.c
idma64.h
img-mdc-dma.c dmaengine: img-mdc: remove unused ‘prev_phys’ 2016-12-12 22:25:22 +05:30
imx-dma.c dmaengine: imx-dma: convert callback to helper function 2016-08-08 08:11:39 +05:30
imx-sdma.c dmaengine: imx-sdma - correct the dma transfer residue calculation 2016-11-25 11:05:14 +05:30
iop-adma.c dmaengine: iop-adma: convert callback to helper function 2016-08-08 08:11:39 +05:30
k3dma.c dmaengine: k3dma: move to dma_pool_zalloc 2016-12-08 21:24:21 +05:30
Kconfig dmaengine updates for 4.10-rc1 2016-12-14 20:42:45 -08:00
lpc18xx-dmamux.c
Makefile dmaengine: st_fdma: Add STMicroelectronics FDMA engine driver support 2016-10-18 20:12:06 +05:30
mic_x100_dma.c dmaengine: mic_x100_dma: remove unused ‘data’ 2016-12-12 22:25:22 +05:30
mic_x100_dma.h
mmp_pdma.c dmaengine: mmp_pdma: convert callback to helper function 2016-08-08 08:11:39 +05:30
mmp_tdma.c Merge branch 'topic/err_reporting' into for-linus 2016-10-03 09:17:33 +05:30
moxart-dma.c dmaengine: moxart: remove NO_IRQ 2016-09-05 16:40:52 +05:30
mpc512x_dma.c Merge branch 'topic/err_reporting' into for-linus 2016-10-03 09:17:33 +05:30
mv_xor_v2.c dmaengine: mv_xor_v2: remove trailing whitespace 2016-07-12 10:10:00 +05:30
mv_xor.c dmaengine: mv_xor: use builtin_platform_driver 2016-11-25 11:47:39 +05:30
mv_xor.h dmaengine: mv_xor: Add support for scatter-gather DMA mode 2016-11-25 11:16:36 +05:30
mxs-dma.c Merge branch 'topic/no_irq' into for-linus 2016-10-03 09:18:29 +05:30
nbpfaxi.c dmaengine: nbpfaxi: add optional max-burst property for memory reads/writes 2016-11-14 10:07:58 +05:30
of-dma.c
omap-dma.c dmaengine: omap-dma: Fix the port_window support 2017-01-10 11:08:01 +05:30
pch_dma.c dmaengine: pch_dma: remove unused ‘cookie’ 2016-12-12 22:25:22 +05:30
pl330.c dmaengine: pl330: Fix runtime PM support for terminated transfers 2017-01-03 09:18:13 +05:30
pxa_dma.c Revert "dmaengine: pxa_dma: add support for legacy transition" 2016-10-18 20:14:32 +05:30
s3c24xx-dma.c dmaengine: s3c24xx: remove unused ‘cdata’ 2016-12-12 22:25:22 +05:30
sa11x0-dma.c dmaengine: sa11x0: use correct print specifiers for size_t 2016-09-26 22:29:26 +05:30
sirf-dma.c dmaengine: sirf-dma: remove unused ‘sdesc’ 2016-12-12 22:25:22 +05:30
st_fdma.c dmaengine: st_fdma: Fix the error return code in st_fdma_probe() 2016-10-19 22:29:33 +05:30
st_fdma.h dmaengine: st_fdma: Add STMicroelectronics FDMA driver header file 2016-10-18 20:12:06 +05:30
ste_dma40_ll.c dmaengine: ste_dma40_ll: make d40_width_to_bits static 2016-06-08 08:59:55 +05:30
ste_dma40_ll.h
ste_dma40.c Merge branch 'topic/ste_dma40' into for-linus 2016-10-03 09:35:55 +05:30
stm32-dma.c dmaengine: stm32-dma: Fix null pointer dereference in stm32_dma_tx_status 2017-01-02 09:28:52 +05:30
sun4i-dma.c
sun6i-dma.c dmaengine: sun6i: fix the uninitialized value for v_lli 2016-11-25 11:49:38 +05:30
tegra20-apb-dma.c dmaengine: tegra20-apb-dma: convert callback to helper function 2016-08-08 08:11:41 +05:30
tegra210-adma.c dmaengine: tegra210-adma: Update driver to use of_pm_clk_add_clk 2016-08-22 11:55:05 +05:30
ti-dma-crossbar.c dmaengine: ti-dma-crossbar: Add some 'of_node_put()' in error path. 2017-01-02 10:37:26 +05:30
timb_dma.c dmaengine: timb_dma: convert callback to helper function 2016-08-08 08:11:41 +05:30
TODO
txx9dmac.c dmaengine: txx9dmac: convert callback to helper function 2016-08-08 08:11:41 +05:30
txx9dmac.h
virt-dma.c dmaengine: virt-dma: convert callback to helper function 2016-08-08 08:11:41 +05:30
virt-dma.h dmaengine: virt-dma: move function declarations 2016-10-01 11:41:39 +05:30
xgene-dma.c dmaengine: xgene-dma: move unmap to before callback 2016-08-08 08:11:43 +05:30
zx296702_dma.c dmaengine: zx296702_dma: Use dma_pool_zalloc 2016-11-30 08:50:40 +05:30