[MIPS] Add support for MIPS CMP platform.

Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index ccbea22..ca65469 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -32,8 +32,11 @@
 #define M_COUNTER_OVERFLOW		(1UL      << 31)
 
 #ifdef CONFIG_MIPS_MT_SMP
-#define WHAT		(M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
-#define vpe_id()	smp_processor_id()
+static int cpu_has_mipsmt_pertccounters;
+#define WHAT		(M_TC_EN_VPE | \
+			 M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id))
+#define vpe_id()	(cpu_has_mipsmt_pertccounters ? \
+			0 : cpu_data[smp_processor_id()].vpe_id)
 
 /*
  * The number of bits to shift to convert between counters per core and
@@ -243,11 +246,11 @@
 {
 	if (!(read_c0_config1() & M_CONFIG1_PC))
 		return 0;
-	if (!(r_c0_perfctrl0() & M_PERFCTL_MORE))
+	if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
 		return 1;
-	if (!(r_c0_perfctrl1() & M_PERFCTL_MORE))
+	if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
 		return 2;
-	if (!(r_c0_perfctrl2() & M_PERFCTL_MORE))
+	if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
 		return 3;
 
 	return 4;
@@ -274,8 +277,9 @@
 	return counters;
 }
 
-static inline void reset_counters(int counters)
+static void reset_counters(void *arg)
 {
+	int counters = (int)arg;
 	switch (counters) {
 	case 4:
 		w_c0_perfctrl3(0);
@@ -302,9 +306,12 @@
 		return -ENODEV;
 	}
 
-	reset_counters(counters);
-
-	counters = counters_total_to_per_cpu(counters);
+#ifdef CONFIG_MIPS_MT_SMP
+	cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
+	if (!cpu_has_mipsmt_pertccounters)
+		counters = counters_total_to_per_cpu(counters);
+#endif
+	on_each_cpu(reset_counters, (void *)counters, 0, 1);
 
 	op_model_mipsxx_ops.num_counters = counters;
 	switch (current_cpu_type()) {
@@ -320,6 +327,13 @@
 		op_model_mipsxx_ops.cpu_type = "mips/25K";
 		break;
 
+	case CPU_1004K:
+#if 0
+		/* FIXME: report as 34K for now */
+		op_model_mipsxx_ops.cpu_type = "mips/1004K";
+		break;
+#endif
+
 	case CPU_34K:
 		op_model_mipsxx_ops.cpu_type = "mips/34K";
 		break;
@@ -365,7 +379,7 @@
 	int counters = op_model_mipsxx_ops.num_counters;
 
 	counters = counters_per_cpu_to_total(counters);
-	reset_counters(counters);
+	on_each_cpu(reset_counters, (void *)counters, 0, 1);
 
 	perf_irq = null_perf_irq;
 }