ARM: 6535/1: V6 MPCore v6_dma_inv_range and v6_dma_flush_range RWFO fix
authorValentine Barshak <vbarshak@mvista.com>
Mon, 13 Dec 2010 23:03:16 +0000 (00:03 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 7 Jan 2011 21:58:19 +0000 (13:58 -0800)
commit 85b093bcc5322baa811a03ec73de0909c157f181 upstream.

Cache ownership must be acquired by reading/writing data from the
cache line to make cache operation have the desired effect on the
SMP MPCore CPU. However, the ownership is never acquired in the
v6_dma_inv_range function when cleaning the first line and
flushing the last one, in case the address is not aligned
to D_CACHE_LINE_SIZE boundary.
Fix this by reading/writing data if needed, before performing
cache operations.
While at it, fix v6_dma_flush_range to prevent RWFO outside
the buffer.

Signed-off-by: Valentine Barshak <vbarshak@mvista.com>
Signed-off-by: George G. Davis <gdavis@mvista.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/arm/mm/cache-v6.S

index 86aa689ef1aa2f6b53cf84a717427df11a25ce1e..47010d8114b00f647e2e202b3262fe96238462ca 100644 (file)
@@ -196,6 +196,10 @@ ENTRY(v6_flush_kern_dcache_area)
  *     - end     - virtual end address of region
  */
 v6_dma_inv_range:
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrb    r2, [r0]                        @ read for ownership
+       strb    r2, [r0]                        @ write for ownership
+#endif
        tst     r0, #D_CACHE_LINE_SIZE - 1
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
@@ -204,6 +208,10 @@ v6_dma_inv_range:
        mcrne   p15, 0, r0, c7, c11, 1          @ clean unified line
 #endif
        tst     r1, #D_CACHE_LINE_SIZE - 1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrneb  r2, [r1, #-1]                   @ read for ownership
+       strneb  r2, [r1, #-1]                   @ write for ownership
+#endif
        bic     r1, r1, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
        mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D line
@@ -211,10 +219,6 @@ v6_dma_inv_range:
        mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line
 #endif
 1:
-#ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
-#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c6, 1           @ invalidate D line
 #else
@@ -222,6 +226,10 @@ v6_dma_inv_range:
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlo   r2, [r0]                        @ read for ownership
+       strlo   r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
@@ -256,12 +264,12 @@ v6_dma_clean_range:
  *     - end     - virtual end address of region
  */
 ENTRY(v6_dma_flush_range)
-       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
-1:
 #ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
+       ldrb    r2, [r0]                @ read for ownership
+       strb    r2, [r0]                @ write for ownership
 #endif
+       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
 #else
@@ -269,6 +277,10 @@ ENTRY(v6_dma_flush_range)
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlob  r2, [r0]                        @ read for ownership
+       strlob  r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer