diff options
author | Tony Lindgren <tony@atomide.com> | 2010-09-21 12:16:40 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-04 15:23:36 -0400 |
commit | 81d11955bf0b5ae25e3adbec930cd84840385dae (patch) | |
tree | d58cd15acd7f7f1b90397a5c00fd92193866be4d /arch/arm/include/asm/cacheflush.h | |
parent | f9e417e901e891d139f4d5fd750959e4a862d9f7 (diff) |
ARM: 6405/1: Handle __flush_icache_all for CONFIG_SMP_ON_UP
Do this by adding flush_icache_all to cache_fns for ARMv6 and 7.
As flush_icache_all may neeed to be called from flush_kern_cache_all,
add it as the first entry in the cache_fns.
Note that now we can remove the ARM_ERRATA_411920 dependency
to !SMP so it can be selected on UP ARMv6 processors, such
as omap2.
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include/asm/cacheflush.h')
-rw-r--r-- | arch/arm/include/asm/cacheflush.h | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 4656a24058d2..a3db768ee5cc 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -156,6 +156,12 @@ | |||
156 | * Please note that the implementation of these, and the required | 156 | * Please note that the implementation of these, and the required |
157 | * effects are cache-type (VIVT/VIPT/PIPT) specific. | 157 | * effects are cache-type (VIVT/VIPT/PIPT) specific. |
158 | * | 158 | * |
159 | * flush_icache_all() | ||
160 | * | ||
161 | * Unconditionally clean and invalidate the entire icache. | ||
162 | * Currently only needed for cache-v6.S and cache-v7.S, see | ||
163 | * __flush_icache_all for the generic implementation. | ||
164 | * | ||
159 | * flush_kern_all() | 165 | * flush_kern_all() |
160 | * | 166 | * |
161 | * Unconditionally clean and invalidate the entire cache. | 167 | * Unconditionally clean and invalidate the entire cache. |
@@ -206,6 +212,7 @@ | |||
206 | */ | 212 | */ |
207 | 213 | ||
208 | struct cpu_cache_fns { | 214 | struct cpu_cache_fns { |
215 | void (*flush_icache_all)(void); | ||
209 | void (*flush_kern_all)(void); | 216 | void (*flush_kern_all)(void); |
210 | void (*flush_user_all)(void); | 217 | void (*flush_user_all)(void); |
211 | void (*flush_user_range)(unsigned long, unsigned long, unsigned int); | 218 | void (*flush_user_range)(unsigned long, unsigned long, unsigned int); |
@@ -227,6 +234,7 @@ struct cpu_cache_fns { | |||
227 | 234 | ||
228 | extern struct cpu_cache_fns cpu_cache; | 235 | extern struct cpu_cache_fns cpu_cache; |
229 | 236 | ||
237 | #define __cpuc_flush_icache_all cpu_cache.flush_icache_all | ||
230 | #define __cpuc_flush_kern_all cpu_cache.flush_kern_all | 238 | #define __cpuc_flush_kern_all cpu_cache.flush_kern_all |
231 | #define __cpuc_flush_user_all cpu_cache.flush_user_all | 239 | #define __cpuc_flush_user_all cpu_cache.flush_user_all |
232 | #define __cpuc_flush_user_range cpu_cache.flush_user_range | 240 | #define __cpuc_flush_user_range cpu_cache.flush_user_range |
@@ -246,6 +254,7 @@ extern struct cpu_cache_fns cpu_cache; | |||
246 | 254 | ||
247 | #else | 255 | #else |
248 | 256 | ||
257 | #define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all) | ||
249 | #define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) | 258 | #define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) |
250 | #define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) | 259 | #define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) |
251 | #define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) | 260 | #define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) |
@@ -253,6 +262,7 @@ extern struct cpu_cache_fns cpu_cache; | |||
253 | #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) | 262 | #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) |
254 | #define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) | 263 | #define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) |
255 | 264 | ||
265 | extern void __cpuc_flush_icache_all(void); | ||
256 | extern void __cpuc_flush_kern_all(void); | 266 | extern void __cpuc_flush_kern_all(void); |
257 | extern void __cpuc_flush_user_all(void); | 267 | extern void __cpuc_flush_user_all(void); |
258 | extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); | 268 | extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); |
@@ -291,6 +301,37 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, | |||
291 | /* | 301 | /* |
292 | * Convert calls to our calling convention. | 302 | * Convert calls to our calling convention. |
293 | */ | 303 | */ |
304 | |||
305 | /* Invalidate I-cache */ | ||
306 | #define __flush_icache_all_generic() \ | ||
307 | asm("mcr p15, 0, %0, c7, c5, 0" \ | ||
308 | : : "r" (0)); | ||
309 | |||
310 | /* Invalidate I-cache inner shareable */ | ||
311 | #define __flush_icache_all_v7_smp() \ | ||
312 | asm("mcr p15, 0, %0, c7, c1, 0" \ | ||
313 | : : "r" (0)); | ||
314 | |||
315 | /* | ||
316 | * Optimized __flush_icache_all for the common cases. Note that UP ARMv7 | ||
317 | * will fall through to use __flush_icache_all_generic. | ||
318 | */ | ||
319 | #if (defined(CONFIG_CPU_V7) && defined(CONFIG_CPU_V6)) || \ | ||
320 | defined(CONFIG_SMP_ON_UP) | ||
321 | #define __flush_icache_preferred __cpuc_flush_icache_all | ||
322 | #elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) | ||
323 | #define __flush_icache_preferred __flush_icache_all_v7_smp | ||
324 | #elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920) | ||
325 | #define __flush_icache_preferred __cpuc_flush_icache_all | ||
326 | #else | ||
327 | #define __flush_icache_preferred __flush_icache_all_generic | ||
328 | #endif | ||
329 | |||
330 | static inline void __flush_icache_all(void) | ||
331 | { | ||
332 | __flush_icache_preferred(); | ||
333 | } | ||
334 | |||
294 | #define flush_cache_all() __cpuc_flush_kern_all() | 335 | #define flush_cache_all() __cpuc_flush_kern_all() |
295 | 336 | ||
296 | static inline void vivt_flush_cache_mm(struct mm_struct *mm) | 337 | static inline void vivt_flush_cache_mm(struct mm_struct *mm) |
@@ -366,21 +407,6 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr | |||
366 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | 407 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
367 | extern void flush_dcache_page(struct page *); | 408 | extern void flush_dcache_page(struct page *); |
368 | 409 | ||
369 | static inline void __flush_icache_all(void) | ||
370 | { | ||
371 | #ifdef CONFIG_ARM_ERRATA_411920 | ||
372 | extern void v6_icache_inval_all(void); | ||
373 | v6_icache_inval_all(); | ||
374 | #elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7 | ||
375 | asm("mcr p15, 0, %0, c7, c1, 0 @ invalidate I-cache inner shareable\n" | ||
376 | : | ||
377 | : "r" (0)); | ||
378 | #else | ||
379 | asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" | ||
380 | : | ||
381 | : "r" (0)); | ||
382 | #endif | ||
383 | } | ||
384 | static inline void flush_kernel_vmap_range(void *addr, int size) | 410 | static inline void flush_kernel_vmap_range(void *addr, int size) |
385 | { | 411 | { |
386 | if ((cache_is_vivt() || cache_is_vipt_aliasing())) | 412 | if ((cache_is_vivt() || cache_is_vipt_aliasing())) |