Running the latest kernel on the 4430SDP board with DMA API debugging
enabled results in this:
WARNING: at lib/dma-debug.c:803 check_unmap+0x19c/0x6f0()
NULL NULL: DMA-API: device driver tries to free DMA memory it has not allocated
[device address=0x000000008129901a] [size=260 bytes]
Modules linked in:
Backtrace:
[<
c003cbe0>] (dump_backtrace+0x0/0x10c) from [<
c0278da8>] (dump_stack+0x18/0x1c)
r7:
c1839dc0 r6:
c0198578 r5:
c0304b17 r4:
00000323
[<
c0278d90>] (dump_stack+0x0/0x1c) from [<
c005b158>] (warn_slowpath_common+0x58/0x70)
[<
c005b100>] (warn_slowpath_common+0x0/0x70) from [<
c005b214>] (warn_slowpath_fmt+0x38/0x40)
r8:
c1839e40 r7:
00000000 r6:
00000104 r5:
00000000 r4:
8129901a
[<
c005b1dc>] (warn_slowpath_fmt+0x0/0x40) from [<
c0198578>] (check_unmap+0x19c/0x6f0)
r3:
c03110de r2:
c0304e6b
[<
c01983dc>] (check_unmap+0x0/0x6f0) from [<
c0198cd8>] (debug_dma_unmap_page+0x74/0x80)
[<
c0198c64>] (debug_dma_unmap_page+0x0/0x80) from [<
c01d5ad8>] (omap2_mcspi_work+0x514/0xbf0)
[<
c01d55c4>] (omap2_mcspi_work+0x0/0xbf0) from [<
c006dfb0>] (process_one_work+0x294/0x400)
[<
c006dd1c>] (process_one_work+0x0/0x400) from [<
c006e50c>] (worker_thread+0x220/0x3f8)
[<
c006e2ec>] (worker_thread+0x0/0x3f8) from [<
c00738d0>] (kthread+0x88/0x90)
[<
c0073848>] (kthread+0x0/0x90) from [<
c005e924>] (do_exit+0x0/0x5fc)
r7:
00000013 r6:
c005e924 r5:
c0073848 r4:
c1829ee0
---[ end trace
1b75b31a2719ed20 ]---
I've no idea why this driver uses NULL for dma_unmap_single instead of
the &spi->dev that is laying around just waiting to be used in that
function - but it's an easy fix.
Also replace this comment with a FIXME comment:
/* Do DMA mapping "early" for better error reporting and
* dcache use. Note that if dma_unmap_single() ever starts
* to do real work on ARM, we'd need to clean up mappings
* for previous transfers on *ALL* exits of this loop...
*/
as the comment is not true - we do work in dma_unmap() functions,
particularly on ARMv6 and above. I've corrected the existing unmap
functions but if any others are required they must be added ASAP.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
if (tx != NULL) {
wait_for_completion(&mcspi_dma->dma_tx_completion);
- dma_unmap_single(NULL, xfer->tx_dma, count, DMA_TO_DEVICE);
+ dma_unmap_single(&spi->dev, xfer->tx_dma, count, DMA_TO_DEVICE);
/* for TX_ONLY mode, be sure all words have shifted out */
if (rx == NULL) {
if (rx != NULL) {
wait_for_completion(&mcspi_dma->dma_rx_completion);
- dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE);
+ dma_unmap_single(&spi->dev, xfer->rx_dma, count, DMA_FROM_DEVICE);
omap2_mcspi_set_enable(spi, 0);
if (l & OMAP2_MCSPI_CHCONF_TURBO) {
if (m->is_dma_mapped || len < DMA_MIN_BYTES)
continue;
- /* Do DMA mapping "early" for better error reporting and
- * dcache use. Note that if dma_unmap_single() ever starts
- * to do real work on ARM, we'd need to clean up mappings
- * for previous transfers on *ALL* exits of this loop...
- */
if (tx_buf != NULL) {
t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf,
len, DMA_TO_DEVICE);
dev_dbg(&spi->dev, "dma %cX %d bytes error\n",
'R', len);
if (tx_buf != NULL)
- dma_unmap_single(NULL, t->tx_dma,
+ dma_unmap_single(&spi->dev, t->tx_dma,
len, DMA_TO_DEVICE);
return -EINVAL;
}