aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/oprofile/op_model_mipsxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/oprofile/op_model_mipsxx.c')
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index ccbea229a0e6..da8cbb6899dc 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -31,9 +31,14 @@
31 31
32#define M_COUNTER_OVERFLOW (1UL << 31) 32#define M_COUNTER_OVERFLOW (1UL << 31)
33 33
34static int (*save_perf_irq)(void);
35
34#ifdef CONFIG_MIPS_MT_SMP 36#ifdef CONFIG_MIPS_MT_SMP
35#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) 37static int cpu_has_mipsmt_pertccounters;
36#define vpe_id() smp_processor_id() 38#define WHAT (M_TC_EN_VPE | \
39 M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id))
40#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
41 0 : cpu_data[smp_processor_id()].vpe_id)
37 42
38/* 43/*
39 * The number of bits to shift to convert between counters per core and 44 * The number of bits to shift to convert between counters per core and
@@ -243,11 +248,11 @@ static inline int __n_counters(void)
243{ 248{
244 if (!(read_c0_config1() & M_CONFIG1_PC)) 249 if (!(read_c0_config1() & M_CONFIG1_PC))
245 return 0; 250 return 0;
246 if (!(r_c0_perfctrl0() & M_PERFCTL_MORE)) 251 if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
247 return 1; 252 return 1;
248 if (!(r_c0_perfctrl1() & M_PERFCTL_MORE)) 253 if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
249 return 2; 254 return 2;
250 if (!(r_c0_perfctrl2() & M_PERFCTL_MORE)) 255 if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
251 return 3; 256 return 3;
252 257
253 return 4; 258 return 4;
@@ -274,8 +279,9 @@ static inline int n_counters(void)
274 return counters; 279 return counters;
275} 280}
276 281
277static inline void reset_counters(int counters) 282static void reset_counters(void *arg)
278{ 283{
284 int counters = (int)arg;
279 switch (counters) { 285 switch (counters) {
280 case 4: 286 case 4:
281 w_c0_perfctrl3(0); 287 w_c0_perfctrl3(0);
@@ -302,9 +308,12 @@ static int __init mipsxx_init(void)
302 return -ENODEV; 308 return -ENODEV;
303 } 309 }
304 310
305 reset_counters(counters); 311#ifdef CONFIG_MIPS_MT_SMP
306 312 cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
307 counters = counters_total_to_per_cpu(counters); 313 if (!cpu_has_mipsmt_pertccounters)
314 counters = counters_total_to_per_cpu(counters);
315#endif
316 on_each_cpu(reset_counters, (void *)counters, 0, 1);
308 317
309 op_model_mipsxx_ops.num_counters = counters; 318 op_model_mipsxx_ops.num_counters = counters;
310 switch (current_cpu_type()) { 319 switch (current_cpu_type()) {
@@ -320,6 +329,13 @@ static int __init mipsxx_init(void)
320 op_model_mipsxx_ops.cpu_type = "mips/25K"; 329 op_model_mipsxx_ops.cpu_type = "mips/25K";
321 break; 330 break;
322 331
332 case CPU_1004K:
333#if 0
334 /* FIXME: report as 34K for now */
335 op_model_mipsxx_ops.cpu_type = "mips/1004K";
336 break;
337#endif
338
323 case CPU_34K: 339 case CPU_34K:
324 op_model_mipsxx_ops.cpu_type = "mips/34K"; 340 op_model_mipsxx_ops.cpu_type = "mips/34K";
325 break; 341 break;
@@ -355,6 +371,7 @@ static int __init mipsxx_init(void)
355 return -ENODEV; 371 return -ENODEV;
356 } 372 }
357 373
374 save_perf_irq = perf_irq;
358 perf_irq = mipsxx_perfcount_handler; 375 perf_irq = mipsxx_perfcount_handler;
359 376
360 return 0; 377 return 0;
@@ -365,9 +382,9 @@ static void mipsxx_exit(void)
365 int counters = op_model_mipsxx_ops.num_counters; 382 int counters = op_model_mipsxx_ops.num_counters;
366 383
367 counters = counters_per_cpu_to_total(counters); 384 counters = counters_per_cpu_to_total(counters);
368 reset_counters(counters); 385 on_each_cpu(reset_counters, (void *)counters, 0, 1);
369 386
370 perf_irq = null_perf_irq; 387 perf_irq = save_perf_irq;
371} 388}
372 389
373struct op_mips_model op_model_mipsxx_ops = { 390struct op_mips_model op_model_mipsxx_ops = {