diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-07-13 15:12:54 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-07-29 10:19:30 +0200 |
commit | 27b93d9c1de70bb8191882964d7fa58d01d3c06b (patch) | |
tree | b566ba26a3dca0450ab582a9ed295f53a8b0d800 | |
parent | MIPS: c-r4k: Split r4k_flush_kernel_vmap_range() (diff) | |
download | linux-27b93d9c1de70bb8191882964d7fa58d01d3c06b.tar.xz linux-27b93d9c1de70bb8191882964d7fa58d01d3c06b.zip |
MIPS: c-r4k: Local flush_icache_range cache op override
Allow the permitted cache op types used by
local_r4k_flush_icache_range_ipi() to be overridden by the SMP caller.
This will allow SMP calls to be avoided under certain circumstances,
falling back to a single CPU performing globalized hit cache ops only.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/13803/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r-- | arch/mips/mm/c-r4k.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 004cf41dd717..cfcb336f57a0 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -721,12 +721,16 @@ static void r4k_flush_data_cache_page(unsigned long addr) struct flush_icache_range_args { unsigned long start; unsigned long end; + unsigned int type; }; -static inline void local_r4k_flush_icache_range(unsigned long start, unsigned long end) +static inline void __local_r4k_flush_icache_range(unsigned long start, + unsigned long end, + unsigned int type) { if (!cpu_has_ic_fills_f_dc) { - if (end - start >= dcache_size) { + if (type == R4K_INDEX || + (type & R4K_INDEX && end - start >= dcache_size)) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; @@ -734,7 +738,8 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo } } - if (end - start > icache_size) + if (type == R4K_INDEX || + (type & R4K_INDEX && end - start > icache_size)) r4k_blast_icache(); else { switch (boot_cpu_type()) { @@ -760,13 +765,20 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo #endif } +static inline void local_r4k_flush_icache_range(unsigned long start, + unsigned long end) +{ + __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX); +} + static inline void local_r4k_flush_icache_range_ipi(void *args) { struct flush_icache_range_args *fir_args = args; unsigned long start = fir_args->start; unsigned long end = fir_args->end; + unsigned int type = fir_args->type; - local_r4k_flush_icache_range(start, end); + __local_r4k_flush_icache_range(start, end, type); } static void r4k_flush_icache_range(unsigned long start, unsigned long end) @@ -775,9 +787,9 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; + args.type = R4K_HIT | R4K_INDEX; - r4k_on_each_cpu(R4K_HIT | R4K_INDEX, local_r4k_flush_icache_range_ipi, - &args); + r4k_on_each_cpu(args.type, local_r4k_flush_icache_range_ipi, &args); instruction_hazard(); } |