ARM: 6535/1: V6 MPCore v6_dma_inv_range and v6_dma_flush_range RWFO fix

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.

Cc: stable@kernel.org
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>

authored by Valentine Barshak and committed by Russell King 85b093bc 593c252a

+20 -8
+20 -8
arch/arm/mm/cache-v6.S
··· 203 * - end - virtual end address of region 204 */ 205 v6_dma_inv_range: 206 tst r0, #D_CACHE_LINE_SIZE - 1 207 bic r0, r0, #D_CACHE_LINE_SIZE - 1 208 #ifdef HARVARD_CACHE ··· 215 mcrne p15, 0, r0, c7, c11, 1 @ clean unified line 216 #endif 217 tst r1, #D_CACHE_LINE_SIZE - 1 218 bic r1, r1, #D_CACHE_LINE_SIZE - 1 219 #ifdef HARVARD_CACHE 220 mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line ··· 226 mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line 227 #endif 228 1: 229 - #ifdef CONFIG_DMA_CACHE_RWFO 230 - ldr r2, [r0] @ read for ownership 231 - str r2, [r0] @ write for ownership 232 - #endif 233 #ifdef HARVARD_CACHE 234 mcr p15, 0, r0, c7, c6, 1 @ invalidate D line 235 #else ··· 233 #endif 234 add r0, r0, #D_CACHE_LINE_SIZE 235 cmp r0, r1 236 blo 1b 237 mov r0, #0 238 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer ··· 271 * - end - virtual end address of region 272 */ 273 ENTRY(v6_dma_flush_range) 274 bic r0, r0, #D_CACHE_LINE_SIZE - 1 275 1: 276 - #ifdef CONFIG_DMA_CACHE_RWFO 277 - ldr r2, [r0] @ read for ownership 278 - str r2, [r0] @ write for ownership 279 - #endif 280 #ifdef HARVARD_CACHE 281 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line 282 #else ··· 284 #endif 285 add r0, r0, #D_CACHE_LINE_SIZE 286 cmp r0, r1 287 blo 1b 288 mov r0, #0 289 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
··· 203 * - end - virtual end address of region 204 */ 205 v6_dma_inv_range: 206 + #ifdef CONFIG_DMA_CACHE_RWFO 207 + ldrb r2, [r0] @ read for ownership 208 + strb r2, [r0] @ write for ownership 209 + #endif 210 tst r0, #D_CACHE_LINE_SIZE - 1 211 bic r0, r0, #D_CACHE_LINE_SIZE - 1 212 #ifdef HARVARD_CACHE ··· 211 mcrne p15, 0, r0, c7, c11, 1 @ clean unified line 212 #endif 213 tst r1, #D_CACHE_LINE_SIZE - 1 214 + #ifdef CONFIG_DMA_CACHE_RWFO 215 + ldrneb r2, [r1, #-1] @ read for ownership 216 + strneb r2, [r1, #-1] @ write for ownership 217 + #endif 218 bic r1, r1, #D_CACHE_LINE_SIZE - 1 219 #ifdef HARVARD_CACHE 220 mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line ··· 218 mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line 219 #endif 220 1: 221 #ifdef HARVARD_CACHE 222 mcr p15, 0, r0, c7, c6, 1 @ invalidate D line 223 #else ··· 229 #endif 230 add r0, r0, #D_CACHE_LINE_SIZE 231 cmp r0, r1 232 + #ifdef CONFIG_DMA_CACHE_RWFO 233 + ldrlo r2, [r0] @ read for ownership 234 + strlo r2, [r0] @ write for ownership 235 + #endif 236 blo 1b 237 mov r0, #0 238 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer ··· 263 * - end - virtual end address of region 264 */ 265 ENTRY(v6_dma_flush_range) 266 + #ifdef CONFIG_DMA_CACHE_RWFO 267 + ldrb r2, [r0] @ read for ownership 268 + strb r2, [r0] @ write for ownership 269 + #endif 270 bic r0, r0, #D_CACHE_LINE_SIZE - 1 271 1: 272 #ifdef HARVARD_CACHE 273 mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line 274 #else ··· 276 #endif 277 add r0, r0, #D_CACHE_LINE_SIZE 278 cmp r0, r1 279 + #ifdef CONFIG_DMA_CACHE_RWFO 280 + ldrlob r2, [r0] @ read for ownership 281 + strlob r2, [r0] @ write for ownership 282 + #endif 283 blo 1b 284 mov r0, #0 285 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer