diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2010-05-07 11:26:24 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-05-08 05:44:30 -0400 |
commit | f4d6477f7f073b99220386d62f5bf54bec3482cc (patch) | |
tree | 4c6a13a762f54bfd30550a70226268edcb9d38a7 | |
parent | b5a07faadeb4e0cfd6dcee359e501d4755cab875 (diff) |
ARM: 6111/1: Implement read/write for ownership in the ARMv6 DMA cache ops
The Snoop Control Unit on the ARM11MPCore hardware does not detect the
cache operations and the dma_cache_maint*() functions may leave stale
cache entries on other CPUs. The solution implemented in this patch
performs a Read or Write For Ownership in the ARMv6 DMA cache
maintenance functions. These LDR/STR instructions change the cache line
state to shared or exclusive so that the cache maintenance operation has
the desired effect.
Tested-by: George G. Davis <gdavis@mvista.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/mm/cache-v6.S | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 9d89c67a1cc3..e46ecd847138 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
@@ -211,6 +211,9 @@ v6_dma_inv_range: | |||
211 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line | 211 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line |
212 | #endif | 212 | #endif |
213 | 1: | 213 | 1: |
214 | #ifdef CONFIG_SMP | ||
215 | str r0, [r0] @ write for ownership | ||
216 | #endif | ||
214 | #ifdef HARVARD_CACHE | 217 | #ifdef HARVARD_CACHE |
215 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line | 218 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line |
216 | #else | 219 | #else |
@@ -231,6 +234,9 @@ v6_dma_inv_range: | |||
231 | v6_dma_clean_range: | 234 | v6_dma_clean_range: |
232 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 235 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
233 | 1: | 236 | 1: |
237 | #ifdef CONFIG_SMP | ||
238 | ldr r2, [r0] @ read for ownership | ||
239 | #endif | ||
234 | #ifdef HARVARD_CACHE | 240 | #ifdef HARVARD_CACHE |
235 | mcr p15, 0, r0, c7, c10, 1 @ clean D line | 241 | mcr p15, 0, r0, c7, c10, 1 @ clean D line |
236 | #else | 242 | #else |
@@ -251,6 +257,10 @@ v6_dma_clean_range: | |||
251 | ENTRY(v6_dma_flush_range) | 257 | ENTRY(v6_dma_flush_range) |
252 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 258 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
253 | 1: | 259 | 1: |
260 | #ifdef CONFIG_SMP | ||
261 | ldr r2, [r0] @ read for ownership | ||
262 | str r2, [r0] @ write for ownership | ||
263 | #endif | ||
254 | #ifdef HARVARD_CACHE | 264 | #ifdef HARVARD_CACHE |
255 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | 265 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line |
256 | #else | 266 | #else |
@@ -273,7 +283,9 @@ ENTRY(v6_dma_map_area) | |||
273 | add r1, r1, r0 | 283 | add r1, r1, r0 |
274 | teq r2, #DMA_FROM_DEVICE | 284 | teq r2, #DMA_FROM_DEVICE |
275 | beq v6_dma_inv_range | 285 | beq v6_dma_inv_range |
276 | b v6_dma_clean_range | 286 | teq r2, #DMA_TO_DEVICE |
287 | beq v6_dma_clean_range | ||
288 | b v6_dma_flush_range | ||
277 | ENDPROC(v6_dma_map_area) | 289 | ENDPROC(v6_dma_map_area) |
278 | 290 | ||
279 | /* | 291 | /* |
@@ -283,9 +295,6 @@ ENDPROC(v6_dma_map_area) | |||
283 | * - dir - DMA direction | 295 | * - dir - DMA direction |
284 | */ | 296 | */ |
285 | ENTRY(v6_dma_unmap_area) | 297 | ENTRY(v6_dma_unmap_area) |
286 | add r1, r1, r0 | ||
287 | teq r2, #DMA_TO_DEVICE | ||
288 | bne v6_dma_inv_range | ||
289 | mov pc, lr | 298 | mov pc, lr |
290 | ENDPROC(v6_dma_unmap_area) | 299 | ENDPROC(v6_dma_unmap_area) |
291 | 300 | ||