[MIPS] Allow setting of the cache attribute at run time.
[sfrench/cifs-2.6.git] / arch / mips / mm / c-r4k.c
index 2c4f7e11f0d55fe746d142f764b0e4024f78d686..3d3e53651341000f3f4b0eb6c5da1576c708254c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/linkage.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/bitops.h>
 
 #include <asm/bcache.h>
@@ -93,7 +94,7 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr)
        blast_dcache32_page(addr);
 }
 
-static void __init r4k_blast_dcache_page_setup(void)
+static void __cpuinit r4k_blast_dcache_page_setup(void)
 {
        unsigned long  dc_lsize = cpu_dcache_line_size();
 
@@ -107,7 +108,7 @@ static void __init r4k_blast_dcache_page_setup(void)
 
 static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
 
-static void __init r4k_blast_dcache_page_indexed_setup(void)
+static void __cpuinit r4k_blast_dcache_page_indexed_setup(void)
 {
        unsigned long dc_lsize = cpu_dcache_line_size();
 
@@ -121,7 +122,7 @@ static void __init r4k_blast_dcache_page_indexed_setup(void)
 
 static void (* r4k_blast_dcache)(void);
 
-static void __init r4k_blast_dcache_setup(void)
+static void __cpuinit r4k_blast_dcache_setup(void)
 {
        unsigned long dc_lsize = cpu_dcache_line_size();
 
@@ -206,7 +207,7 @@ static inline void tx49_blast_icache32_page_indexed(unsigned long page)
 
 static void (* r4k_blast_icache_page)(unsigned long addr);
 
-static void __init r4k_blast_icache_page_setup(void)
+static void __cpuinit r4k_blast_icache_page_setup(void)
 {
        unsigned long ic_lsize = cpu_icache_line_size();
 
@@ -223,7 +224,7 @@ static void __init r4k_blast_icache_page_setup(void)
 
 static void (* r4k_blast_icache_page_indexed)(unsigned long addr);
 
-static void __init r4k_blast_icache_page_indexed_setup(void)
+static void __cpuinit r4k_blast_icache_page_indexed_setup(void)
 {
        unsigned long ic_lsize = cpu_icache_line_size();
 
@@ -247,7 +248,7 @@ static void __init r4k_blast_icache_page_indexed_setup(void)
 
 static void (* r4k_blast_icache)(void);
 
-static void __init r4k_blast_icache_setup(void)
+static void __cpuinit r4k_blast_icache_setup(void)
 {
        unsigned long ic_lsize = cpu_icache_line_size();
 
@@ -268,7 +269,7 @@ static void __init r4k_blast_icache_setup(void)
 
 static void (* r4k_blast_scache_page)(unsigned long addr);
 
-static void __init r4k_blast_scache_page_setup(void)
+static void __cpuinit r4k_blast_scache_page_setup(void)
 {
        unsigned long sc_lsize = cpu_scache_line_size();
 
@@ -286,7 +287,7 @@ static void __init r4k_blast_scache_page_setup(void)
 
 static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
 
-static void __init r4k_blast_scache_page_indexed_setup(void)
+static void __cpuinit r4k_blast_scache_page_indexed_setup(void)
 {
        unsigned long sc_lsize = cpu_scache_line_size();
 
@@ -304,7 +305,7 @@ static void __init r4k_blast_scache_page_indexed_setup(void)
 
 static void (* r4k_blast_scache)(void);
 
-static void __init r4k_blast_scache_setup(void)
+static void __cpuinit r4k_blast_scache_setup(void)
 {
        unsigned long sc_lsize = cpu_scache_line_size();
 
@@ -361,6 +362,16 @@ static inline int has_valid_asid(const struct mm_struct *mm)
 #endif
 }
 
+static void r4k__flush_cache_vmap(void)
+{
+       r4k_blast_dcache();
+}
+
+static void r4k__flush_cache_vunmap(void)
+{
+       r4k_blast_dcache();
+}
+
 static inline void local_r4k_flush_cache_range(void * args)
 {
        struct vm_area_struct *vma = args;
@@ -691,11 +702,11 @@ static inline void rm7k_erratum31(void)
        }
 }
 
-static char *way_string[] __initdata = { NULL, "direct mapped", "2-way",
+static char *way_string[] __cpuinitdata = { NULL, "direct mapped", "2-way",
        "3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
 };
 
-static void __init probe_pcache(void)
+static void __cpuinit probe_pcache(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
        unsigned int config = read_c0_config();
@@ -1016,7 +1027,7 @@ static void __init probe_pcache(void)
  * executes in KSEG1 space or else you will crash and burn badly.  You have
  * been warned.
  */
-static int __init probe_scache(void)
+static int __cpuinit probe_scache(void)
 {
        unsigned long flags, addr, begin, end, pow2;
        unsigned int config = read_c0_config();
@@ -1095,7 +1106,7 @@ extern int r5k_sc_init(void);
 extern int rm7k_sc_init(void);
 extern int mips_sc_init(void);
 
-static void __init setup_scache(void)
+static void __cpuinit setup_scache(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
        unsigned int config = read_c0_config();
@@ -1206,9 +1217,25 @@ void au1x00_fixup_config_od(void)
        }
 }
 
-static void __init coherency_setup(void)
+static int __cpuinitdata cca = -1;
+
+static int __init cca_setup(char *str)
+{
+       get_option(&str, &cca);
+
+       return 1;
+}
+
+__setup("cca=", cca_setup);
+
+static void __cpuinit coherency_setup(void)
 {
-       change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
+       if (cca < 0 || cca > 7)
+               cca = read_c0_config() & CONF_CM_CMASK;
+       _page_cachable_default = cca << _CACHE_SHIFT;
+
+       pr_debug("Using cache attribute %d\n", cca);
+       change_c0_config(CONF_CM_CMASK, cca);
 
        /*
         * c0_status.cu=0 specifies that updates by the sc instruction use
@@ -1238,7 +1265,7 @@ static void __init coherency_setup(void)
        }
 }
 
-void __init r4k_cache_init(void)
+void __cpuinit r4k_cache_init(void)
 {
        extern void build_clear_page(void);
        extern void build_copy_page(void);
@@ -1281,6 +1308,10 @@ void __init r4k_cache_init(void)
                                        PAGE_SIZE - 1);
        else
                shm_align_mask = PAGE_SIZE-1;
+
+       __flush_cache_vmap      = r4k__flush_cache_vmap;
+       __flush_cache_vunmap    = r4k__flush_cache_vunmap;
+
        flush_cache_all         = cache_noop;
        __flush_cache_all       = r4k___flush_cache_all;
        flush_cache_mm          = r4k_flush_cache_mm;