MIPS: Introduce machinery for testing for MIPSxxR1/2.
    
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index d00f876..fac48ad 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -435,6 +435,9 @@
 	}
 }
 
+static char unknown_isa[] __initdata = KERN_ERR \
+	"Unsupported ISA type, c0.config0: %d.";
+
 static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 {
 	unsigned int config0;
@@ -447,16 +450,37 @@
 	isa = (config0 & MIPS_CONF_AT) >> 13;
 	switch (isa) {
 	case 0:
-		c->isa_level = MIPS_CPU_ISA_M32R1;
+		switch ((config0 >> 10) & 7) {
+		case 0:
+			c->isa_level = MIPS_CPU_ISA_M32R1;
+			break;
+		case 1:
+			c->isa_level = MIPS_CPU_ISA_M32R2;
+			break;
+		default:
+			goto unknown;
+		}
 		break;
 	case 2:
-		c->isa_level = MIPS_CPU_ISA_M64R1;
+		switch ((config0 >> 10) & 7) {
+		case 0:
+			c->isa_level = MIPS_CPU_ISA_M64R1;
+			break;
+		case 1:
+			c->isa_level = MIPS_CPU_ISA_M64R2;
+			break;
+		default:
+			goto unknown;
+		}
 		break;
 	default:
-		panic("Unsupported ISA type, cp0.config0.at: %d.", isa);
+		goto unknown;
 	}
 
 	return config0 & MIPS_CONF_M;
+
+unknown:
+	panic(unknown_isa, config0);
 }
 
 static inline unsigned int decode_config1(struct cpuinfo_mips *c)
@@ -568,7 +592,6 @@
 		break;
 	case PRID_IMP_34K:
 		c->cputype = CPU_34K;
-		c->isa_level = MIPS_CPU_ISA_M32R1;
 		break;
 	}
 }
@@ -691,7 +714,9 @@
 		c->fpu_id = cpu_get_fpu_id();
 
 		if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
-		    c->isa_level == MIPS_CPU_ISA_M64R1) {
+		    c->isa_level == MIPS_CPU_ISA_M32R2 ||
+		    c->isa_level == MIPS_CPU_ISA_M64R1 ||
+		    c->isa_level == MIPS_CPU_ISA_M64R2) {
 			if (c->fpu_id & MIPS_FPIR_3D)
 				c->ases |= MIPS_ASE_MIPS3D;
 		}
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 174959b..07e125c 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -628,9 +628,9 @@
 			mips_hpt_init = c0_hpt_init;
 		}
 
-		if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32R1) ||
-			 (current_cpu_data.isa_level == MIPS_CPU_ISA_I) ||
-			 (current_cpu_data.isa_level == MIPS_CPU_ISA_II))
+		if (cpu_has_mips32r1 || cpu_has_mips32r2 ||
+		    (current_cpu_data.isa_level == MIPS_CPU_ISA_I) ||
+		    (current_cpu_data.isa_level == MIPS_CPU_ISA_II))
 			/*
 			 * We need to calibrate the counter but we don't have
 			 * 64-bit division.
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index 03627cfb..f8be4a4 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -144,6 +144,18 @@
 # ifndef cpu_has_64bit_addresses
 # define cpu_has_64bit_addresses	0
 # endif
+# ifndef cpu_has_mips32r1
+# define cpu_has_mips32r1	(cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1)
+# endif
+# ifndef cpu_has_mips32r2
+# define cpu_has_mips32r2	(cpu_data[0].isa_level & MIPS_CPU_ISA_M32R2)
+# endif
+# ifndef cpu_has_mips64r1
+# define cpu_has_mips64r1	0
+# endif
+# ifndef cpu_has_mips64r2
+# define cpu_has_mips64r2	0
+# endif
 #endif
 
 #ifdef CONFIG_64BIT
@@ -162,6 +174,18 @@
 # ifndef cpu_has_64bit_addresses
 # define cpu_has_64bit_addresses	1
 # endif
+# ifndef cpu_has_mips32r1
+# define cpu_has_mips32r1	0
+# endif
+# ifndef cpu_has_mips32r2
+# define cpu_has_mips32r2	0
+# endif
+# ifndef cpu_has_mips64r1
+# define cpu_has_mips64r1	(cpu_data[0].isa_level & MIPS_CPU_ISA_M64R1)
+# endif
+# ifndef cpu_has_mips64r2
+# define cpu_has_mips64r2	(cpu_data[0].isa_level & MIPS_CPU_ISA_M64R2)
+# endif
 #endif
 
 #ifdef CONFIG_CPU_MIPSR2
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index 256fe13..48c37c4 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -210,7 +210,9 @@
 #define MIPS_CPU_ISA_IV		(0x00000004 | MIPS_CPU_ISA_64BIT)
 #define MIPS_CPU_ISA_V		(0x00000005 | MIPS_CPU_ISA_64BIT)
 #define MIPS_CPU_ISA_M32R1	0x00000020
-#define MIPS_CPU_ISA_M64R1	(0x00000040 | MIPS_CPU_ISA_64BIT)
+#define MIPS_CPU_ISA_M32R2	0x00000040
+#define MIPS_CPU_ISA_M64R1	(0x00000080 | MIPS_CPU_ISA_64BIT)
+#define MIPS_CPU_ISA_M64R2	(0x00000100 | MIPS_CPU_ISA_64BIT)
 
 /*
  * CPU Option encodings
diff --git a/include/asm-mips/mach-ip22/cpu-feature-overrides.h b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
index ab97146..2a37bed 100644
--- a/include/asm-mips/mach-ip22/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip22/cpu-feature-overrides.h
@@ -34,4 +34,9 @@
 #define cpu_has_nofpuex		0
 #define cpu_has_64bits		1
 
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
 #endif /* __ASM_MACH_IP22_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
index 4c8a900..2d2f5b9 100644
--- a/include/asm-mips/mach-ip27/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip27/cpu-feature-overrides.h
@@ -37,4 +37,9 @@
 #define cpu_icache_line_size()	64
 #define cpu_scache_line_size()	128
 
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
 #endif /* __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
index ab37fc1..b80c307 100644
--- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h
@@ -39,4 +39,9 @@
 #define cpu_has_ic_fills_f_dc	0
 #define cpu_has_dsp		0
 
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
 #endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ja/cpu-feature-overrides.h b/include/asm-mips/mach-ja/cpu-feature-overrides.h
index a0fde40..90ff087 100644
--- a/include/asm-mips/mach-ja/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ja/cpu-feature-overrides.h
@@ -37,4 +37,9 @@
 #define cpu_icache_line_size()	32
 #define cpu_scache_line_size()	32
 
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
 #endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
index 825c5f6..782b986 100644
--- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
@@ -40,4 +40,9 @@
 #define cpu_icache_line_size()	32
 #define cpu_scache_line_size()	32
 
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
 #endif /* __ASM_MACH_JA_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-rm200/cpu-feature-overrides.h b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
index 79f9b06..91e7cf5 100644
--- a/include/asm-mips/mach-rm200/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-rm200/cpu-feature-overrides.h
@@ -40,4 +40,9 @@
 #define cpu_icache_line_size()	32
 #define cpu_scache_line_size()	0	/* No S-cache on R5000 I think ...  */
 
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
 #endif /* __ASM_MACH_RM200_CPU_FEATURE_OVERRIDES_H */
diff --git a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
index 463d051..3073542 100644
--- a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
+++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
@@ -37,4 +37,9 @@
 #define cpu_icache_line_size()	32
 #define cpu_scache_line_size()	32
 
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+
 #endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */