diff options
Diffstat (limited to 'arch/mips/mm/c-r4k.c')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 3d3e5365134..643c8bcffff 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -54,6 +54,12 @@ static inline void r4k_on_each_cpu(void (*func) (void *info), void *info, preempt_enable(); } +#if defined(CONFIG_MIPS_CMP) +#define cpu_has_safe_index_cacheops 0 +#else +#define cpu_has_safe_index_cacheops 1 +#endif + /* * Must die. */ @@ -482,6 +488,8 @@ static inline void local_r4k_flush_cache_page(void *args) if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { r4k_blast_dcache_page(addr); + if (exec && !cpu_icache_snoops_remote_store) + r4k_blast_scache_page(addr); } if (exec) { if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { @@ -584,7 +592,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) * subset property so we have to flush the primary caches * explicitly */ - if (size >= dcache_size) { + if (cpu_has_safe_index_cacheops && size >= dcache_size) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; @@ -607,7 +615,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) return; } - if (size >= dcache_size) { + if (cpu_has_safe_index_cacheops && size >= dcache_size) { r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; @@ -969,6 +977,7 @@ static void __cpuinit probe_pcache(void) case CPU_24K: case CPU_34K: case CPU_74K: + case CPU_1004K: if ((read_c0_config7() & (1 << 16))) { /* effectively physically indexed dcache, thus no virtual aliases. */ @@ -1265,6 +1274,20 @@ static void __cpuinit coherency_setup(void) } } +#if defined(CONFIG_DMA_NONCOHERENT) + +static int __cpuinitdata coherentio; + +static int __init setcoherentio(char *str) +{ + coherentio = 1; + + return 1; +} + +__setup("coherentio", setcoherentio); +#endif + void __cpuinit r4k_cache_init(void) { extern void build_clear_page(void); @@ -1324,14 +1347,22 @@ void __cpuinit r4k_cache_init(void) flush_data_cache_page = r4k_flush_data_cache_page; flush_icache_range = r4k_flush_icache_range; -#ifdef CONFIG_DMA_NONCOHERENT - _dma_cache_wback_inv = r4k_dma_cache_wback_inv; - _dma_cache_wback = r4k_dma_cache_wback_inv; - _dma_cache_inv = r4k_dma_cache_inv; +#if defined(CONFIG_DMA_NONCOHERENT) + if (coherentio) { + _dma_cache_wback_inv = (void *)cache_noop; + _dma_cache_wback = (void *)cache_noop; + _dma_cache_inv = (void *)cache_noop; + } else { + _dma_cache_wback_inv = r4k_dma_cache_wback_inv; + _dma_cache_wback = r4k_dma_cache_wback_inv; + _dma_cache_inv = r4k_dma_cache_inv; + } #endif build_clear_page(); build_copy_page(); +#if !defined(CONFIG_MIPS_CMP) local_r4k___flush_cache_all(NULL); +#endif coherency_setup(); } |