aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2010-06-16 05:12:10 -0400
committerMike Frysinger <vapier@gentoo.org>2010-08-06 12:55:50 -0400
commitd1401e1dc22606a91f577ad3dfd68ae7e60e0357 (patch)
tree6c59463c60fd4ada2b5d4974afaa30be7059c67f /arch/blackfin/kernel
parent502c8a0e07450ff886b80a11150a123bae92f3f7 (diff)
Blackfin: fix DMA/cache bug when resuming from suspend to RAM
The dma_memcpy() function takes care of flushing different caches for us. Normally this is what we want, but when resuming from mem, we don't yet have caches enabled. If these functions happen to be placed into L1 mem (which is what we're trying to relocate), then things aren't going to work. So define a non-cache dma_memcpy() variant to utilize in situations like this. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 26403d1c9e65..1e485dfdc9f2 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -450,7 +450,6 @@ void *dma_memcpy(void *pdst, const void *psrc, size_t size)
450{ 450{
451 unsigned long dst = (unsigned long)pdst; 451 unsigned long dst = (unsigned long)pdst;
452 unsigned long src = (unsigned long)psrc; 452 unsigned long src = (unsigned long)psrc;
453 size_t bulk, rest;
454 453
455 if (bfin_addr_dcacheable(src)) 454 if (bfin_addr_dcacheable(src))
456 blackfin_dcache_flush_range(src, src + size); 455 blackfin_dcache_flush_range(src, src + size);
@@ -458,6 +457,22 @@ void *dma_memcpy(void *pdst, const void *psrc, size_t size)
458 if (bfin_addr_dcacheable(dst)) 457 if (bfin_addr_dcacheable(dst))
459 blackfin_dcache_invalidate_range(dst, dst + size); 458 blackfin_dcache_invalidate_range(dst, dst + size);
460 459
460 return dma_memcpy_nocache(pdst, psrc, size);
461}
462EXPORT_SYMBOL(dma_memcpy);
463
464/**
465 * dma_memcpy_nocache - DMA memcpy under mutex lock
466 * - No cache flush/invalidate
467 *
468 * Do not check arguments before starting the DMA memcpy. Break the transfer
469 * up into two pieces. The first transfer is in multiples of 64k and the
470 * second transfer is the piece smaller than 64k.
471 */
472void *dma_memcpy_nocache(void *pdst, const void *psrc, size_t size)
473{
474 size_t bulk, rest;
475
461 bulk = size & ~0xffff; 476 bulk = size & ~0xffff;
462 rest = size - bulk; 477 rest = size - bulk;
463 if (bulk) 478 if (bulk)
@@ -465,7 +480,7 @@ void *dma_memcpy(void *pdst, const void *psrc, size_t size)
465 _dma_memcpy(pdst + bulk, psrc + bulk, rest); 480 _dma_memcpy(pdst + bulk, psrc + bulk, rest);
466 return pdst; 481 return pdst;
467} 482}
468EXPORT_SYMBOL(dma_memcpy); 483EXPORT_SYMBOL(dma_memcpy_nocache);
469 484
470/** 485/**
471 * safe_dma_memcpy - DMA memcpy w/argument checking 486 * safe_dma_memcpy - DMA memcpy w/argument checking