Blackfin arch: flush/inv the correct range when using write back cache and fix bugs find by dmacopy

 - flush/inv the correct range
 - dmacopy test failed when policy is write_back - invalidate before dma
   http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3367
   It's the cache invalidate what is causing the issue.
   There is no invalidate only instruction it's always: FLUSHINV
   So when we "invalidate" after the DMA we might (do) overwrite freshly 
   dma'ed data by dirty Cache WB content.

   Fixed by moving the "invalidate" at the beginning of dma_memcpy.

Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>

diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 17edd65..e19164f 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -436,6 +436,10 @@
 		blackfin_dcache_flush_range((unsigned int)src,
 					    (unsigned int)(src + size));
 
+	if ((unsigned long)dest < memory_end)
+		blackfin_dcache_invalidate_range((unsigned int)dest,
+						 (unsigned int)(dest + size));
+
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
 
 	if ((unsigned long)src < (unsigned long)dest)
@@ -543,6 +547,8 @@
 		}
 	}
 
+	SSYNC();
+
 	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
 		;
 
@@ -552,9 +558,6 @@
 	bfin_write_MDMA_S0_CONFIG(0);
 	bfin_write_MDMA_D0_CONFIG(0);
 
-	if ((unsigned long)dest < memory_end)
-		blackfin_dcache_invalidate_range((unsigned int)dest,
-						 (unsigned int)(dest + size));
 	local_irq_restore(flags);
 
 	return dest;
@@ -589,7 +592,8 @@
 
 	local_irq_save(flags);
 
-	blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+	blackfin_dcache_flush_range((unsigned int)buf,
+			 (unsigned int)(buf) + len);
 
 	bfin_write_MDMA_D0_START_ADDR(addr);
 	bfin_write_MDMA_D0_X_COUNT(len);
@@ -604,6 +608,8 @@
 	bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
 	bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
 
+	SSYNC();
+
 	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -620,6 +626,9 @@
 {
 	unsigned long flags;
 
+	blackfin_dcache_invalidate_range((unsigned int)buf,
+			 (unsigned int)(buf) + len);
+
 	local_irq_save(flags);
 	bfin_write_MDMA_D0_START_ADDR(buf);
 	bfin_write_MDMA_D0_X_COUNT(len);
@@ -634,7 +643,7 @@
 	bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
 	bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
 
-	blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len);
+	SSYNC();
 
 	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
@@ -653,7 +662,8 @@
 
 	local_irq_save(flags);
 
-	blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+	blackfin_dcache_flush_range((unsigned int)buf,
+			 (unsigned int)(buf) + len * sizeof(short));
 
 	bfin_write_MDMA_D0_START_ADDR(addr);
 	bfin_write_MDMA_D0_X_COUNT(len);
@@ -668,6 +678,8 @@
 	bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
 	bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
 
+	SSYNC();
+
 	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -683,6 +695,9 @@
 {
 	unsigned long flags;
 
+	blackfin_dcache_invalidate_range((unsigned int)buf,
+			 (unsigned int)(buf) + len * sizeof(short));
+
 	local_irq_save(flags);
 
 	bfin_write_MDMA_D0_START_ADDR(buf);
@@ -698,7 +713,7 @@
 	bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
 	bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
 
-	blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len);
+	SSYNC();
 
 	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
@@ -717,7 +732,8 @@
 
 	local_irq_save(flags);
 
-	blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+	blackfin_dcache_flush_range((unsigned int)buf,
+			 (unsigned int)(buf) + len * sizeof(long));
 
 	bfin_write_MDMA_D0_START_ADDR(addr);
 	bfin_write_MDMA_D0_X_COUNT(len);
@@ -732,6 +748,8 @@
 	bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
 	bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
 
+	SSYNC();
+
 	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
 	bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -747,6 +765,9 @@
 {
 	unsigned long flags;
 
+	blackfin_dcache_invalidate_range((unsigned int)buf,
+			 (unsigned int)(buf) + len * sizeof(long));
+
 	local_irq_save(flags);
 
 	bfin_write_MDMA_D0_START_ADDR(buf);
@@ -762,7 +783,7 @@
 	bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
 	bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
 
-	blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len);
+	SSYNC();
 
 	while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));