diff options
Diffstat (limited to 'arch/mips/oprofile/op_model_mipsxx.c')
-rw-r--r-- | arch/mips/oprofile/op_model_mipsxx.c | 39 |
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 | ||
34 | static 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())) | 37 | static 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 | ||
277 | static inline void reset_counters(int counters) | 282 | static 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 | ||
373 | struct op_mips_model op_model_mipsxx_ops = { | 390 | struct op_mips_model op_model_mipsxx_ops = { |