Commit 27b93d9c authored by James Hogan's avatar James Hogan Committed by Ralf Baechle

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: default avatarJames 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent a9341ae2
...@@ -721,12 +721,16 @@ static void r4k_flush_data_cache_page(unsigned long addr) ...@@ -721,12 +721,16 @@ static void r4k_flush_data_cache_page(unsigned long addr)
struct flush_icache_range_args { struct flush_icache_range_args {
unsigned long start; unsigned long start;
unsigned long end; 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 (!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(); r4k_blast_dcache();
} else { } else {
R4600_HIT_CACHEOP_WAR_IMPL; R4600_HIT_CACHEOP_WAR_IMPL;
...@@ -734,7 +738,8 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo ...@@ -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(); r4k_blast_icache();
else { else {
switch (boot_cpu_type()) { switch (boot_cpu_type()) {
...@@ -760,13 +765,20 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo ...@@ -760,13 +765,20 @@ static inline void local_r4k_flush_icache_range(unsigned long start, unsigned lo
#endif #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) static inline void local_r4k_flush_icache_range_ipi(void *args)
{ {
struct flush_icache_range_args *fir_args = args; struct flush_icache_range_args *fir_args = args;
unsigned long start = fir_args->start; unsigned long start = fir_args->start;
unsigned long end = fir_args->end; 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) 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) ...@@ -775,9 +787,9 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
args.start = start; args.start = start;
args.end = end; args.end = end;
args.type = R4K_HIT | R4K_INDEX;
r4k_on_each_cpu(R4K_HIT | R4K_INDEX, local_r4k_flush_icache_range_ipi, r4k_on_each_cpu(args.type, local_r4k_flush_icache_range_ipi, &args);
&args);
instruction_hazard(); instruction_hazard();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment