diff options
Diffstat (limited to 'arch/arm/common/dmabounce.c')
-rw-r--r-- | arch/arm/common/dmabounce.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index 5797b1b100a1..9d63a01214eb 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/dmapool.h> | 30 | #include <linux/dmapool.h> |
31 | #include <linux/list.h> | 31 | #include <linux/list.h> |
32 | 32 | ||
33 | #include <asm/cacheflush.h> | ||
34 | |||
33 | #undef DEBUG | 35 | #undef DEBUG |
34 | 36 | ||
35 | #undef STATS | 37 | #undef STATS |
@@ -302,12 +304,24 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | |||
302 | 304 | ||
303 | DO_STATS ( device_info->bounce_count++ ); | 305 | DO_STATS ( device_info->bounce_count++ ); |
304 | 306 | ||
305 | if ((dir == DMA_FROM_DEVICE) || | 307 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { |
306 | (dir == DMA_BIDIRECTIONAL)) { | 308 | unsigned long ptr; |
309 | |||
307 | dev_dbg(dev, | 310 | dev_dbg(dev, |
308 | "%s: copy back safe %p to unsafe %p size %d\n", | 311 | "%s: copy back safe %p to unsafe %p size %d\n", |
309 | __func__, buf->safe, buf->ptr, size); | 312 | __func__, buf->safe, buf->ptr, size); |
310 | memcpy(buf->ptr, buf->safe, size); | 313 | memcpy(buf->ptr, buf->safe, size); |
314 | |||
315 | /* | ||
316 | * DMA buffers must have the same cache properties | ||
317 | * as if they were really used for DMA - which means | ||
318 | * data must be written back to RAM. Note that | ||
319 | * we don't use dmac_flush_range() here for the | ||
320 | * bidirectional case because we know the cache | ||
321 | * lines will be coherent with the data written. | ||
322 | */ | ||
323 | ptr = (unsigned long)buf->ptr; | ||
324 | dmac_clean_range(ptr, ptr + size); | ||
311 | } | 325 | } |
312 | free_safe_buffer(device_info, buf); | 326 | free_safe_buffer(device_info, buf); |
313 | } | 327 | } |