Merge tag 'renesas-soc-for-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git...
[firefly-linux-kernel-4.4.55.git] / arch / mips / mm / c-r4k.c
index f749f687ee87796e118a13d9807a917b54549d69..627883bc6d5f29f4a4510373ddb8e552398cb5ed 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/highmem.h>
 #include <linux/kernel.h>
 #include <linux/linkage.h>
+#include <linux/preempt.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
@@ -24,6 +25,7 @@
 #include <asm/cacheops.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
+#include <asm/cpu-type.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -601,6 +603,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
        /* Catch bad driver code */
        BUG_ON(size == 0);
 
+       preempt_disable();
        if (cpu_has_inclusive_pcaches) {
                if (size >= scache_size)
                        r4k_blast_scache();
@@ -621,6 +624,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
                R4600_HIT_CACHEOP_WAR_IMPL;
                blast_dcache_range(addr, addr + size);
        }
+       preempt_enable();
 
        bc_wback_inv(addr, size);
        __sync();
@@ -631,6 +635,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
        /* Catch bad driver code */
        BUG_ON(size == 0);
 
+       preempt_disable();
        if (cpu_has_inclusive_pcaches) {
                if (size >= scache_size)
                        r4k_blast_scache();
@@ -655,6 +660,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
                R4600_HIT_CACHEOP_WAR_IMPL;
                blast_inv_dcache_range(addr, addr + size);
        }
+       preempt_enable();
 
        bc_inv(addr, size);
        __sync();
@@ -780,20 +786,30 @@ static inline void rm7k_erratum31(void)
 
 static inline void alias_74k_erratum(struct cpuinfo_mips *c)
 {
+       unsigned int imp = c->processor_id & PRID_IMP_MASK;
+       unsigned int rev = c->processor_id & PRID_REV_MASK;
+
        /*
         * Early versions of the 74K do not update the cache tags on a
         * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG
         * aliases. In this case it is better to treat the cache as always
         * having aliases.
         */
-       if ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(2, 4, 0))
-               c->dcache.flags |= MIPS_CACHE_VTAG;
-       if ((c->processor_id & 0xff) == PRID_REV_ENCODE_332(2, 4, 0))
-               write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
-       if (((c->processor_id & 0xff00) == PRID_IMP_1074K) &&
-           ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(1, 1, 0))) {
-               c->dcache.flags |= MIPS_CACHE_VTAG;
-               write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
+       switch (imp) {
+       case PRID_IMP_74K:
+               if (rev <= PRID_REV_ENCODE_332(2, 4, 0))
+                       c->dcache.flags |= MIPS_CACHE_VTAG;
+               if (rev == PRID_REV_ENCODE_332(2, 4, 0))
+                       write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
+               break;
+       case PRID_IMP_1074K:
+               if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) {
+                       c->dcache.flags |= MIPS_CACHE_VTAG;
+                       write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
+               }
+               break;
+       default:
+               BUG();
        }
 }
 
@@ -809,7 +825,7 @@ static void probe_pcache(void)
        unsigned long config1;
        unsigned int lsize;
 
-       switch (c->cputype) {
+       switch (current_cpu_type()) {
        case CPU_R4600:                 /* QED style two way caches? */
        case CPU_R4700:
        case CPU_R5000:
@@ -1025,7 +1041,8 @@ static void probe_pcache(void)
         * presumably no vendor is shipping his hardware in the "bad"
         * configuration.
         */
-       if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 &&
+       if ((prid & PRID_IMP_MASK) == PRID_IMP_R4000 &&
+           (prid & PRID_REV_MASK) < PRID_REV_R4400 &&
            !(config & CONF_SC) && c->icache.linesz != 16 &&
            PAGE_SIZE <= 0x8000)
                panic("Improper R4000SC processor configuration detected");
@@ -1045,7 +1062,7 @@ static void probe_pcache(void)
         * normally they'd suffer from aliases but magic in the hardware deals
         * with that for us so we don't need to take care ourselves.
         */
-       switch (c->cputype) {
+       switch (current_cpu_type()) {
        case CPU_20KC:
        case CPU_25KF:
        case CPU_SB1:
@@ -1065,7 +1082,7 @@ static void probe_pcache(void)
        case CPU_34K:
        case CPU_74K:
        case CPU_1004K:
-               if (c->cputype == CPU_74K)
+               if (current_cpu_type() == CPU_74K)
                        alias_74k_erratum(c);
                if ((read_c0_config7() & (1 << 16))) {
                        /* effectively physically indexed dcache,
@@ -1078,7 +1095,7 @@ static void probe_pcache(void)
                        c->dcache.flags |= MIPS_CACHE_ALIASES;
        }
 
-       switch (c->cputype) {
+       switch (current_cpu_type()) {
        case CPU_20KC:
                /*
                 * Some older 20Kc chips doesn't have the 'VI' bit in
@@ -1207,7 +1224,7 @@ static void setup_scache(void)
         * processors don't have a S-cache that would be relevant to the
         * Linux memory management.
         */
-       switch (c->cputype) {
+       switch (current_cpu_type()) {
        case CPU_R4000SC:
        case CPU_R4000MC:
        case CPU_R4400SC:
@@ -1384,9 +1401,8 @@ static void r4k_cache_error_setup(void)
 {
        extern char __weak except_vec2_generic;
        extern char __weak except_vec2_sb1;
-       struct cpuinfo_mips *c = &current_cpu_data;
 
-       switch (c->cputype) {
+       switch (current_cpu_type()) {
        case CPU_SB1:
        case CPU_SB1A:
                set_uncached_handler(0x100, &except_vec2_sb1, 0x80);