diff options
Diffstat (limited to 'arch/mips/oprofile')
-rw-r--r-- | arch/mips/oprofile/common.c | 1 | ||||
-rw-r--r-- | arch/mips/oprofile/op_impl.h | 1 | ||||
-rw-r--r-- | arch/mips/oprofile/op_model_mipsxx.c | 39 |
3 files changed, 29 insertions, 12 deletions
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index aa52aa146ce..b5f6f71b27b 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -80,6 +80,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_24K: case CPU_25KF: case CPU_34K: + case CPU_1004K: case CPU_74K: case CPU_SB1: case CPU_SB1A: diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h index fa6b4aae752..2bfc17c3010 100644 --- a/arch/mips/oprofile/op_impl.h +++ b/arch/mips/oprofile/op_impl.h @@ -10,7 +10,6 @@ #ifndef OP_IMPL_H #define OP_IMPL_H 1 -extern int null_perf_irq(void); extern int (*perf_irq)(void); /* Per-counter configuration as set via oprofilefs. */ diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index ccbea229a0e..da8cbb6899d 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -31,9 +31,14 @@ #define M_COUNTER_OVERFLOW (1UL << 31) +static int (*save_perf_irq)(void); + #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 +248,11 @@ static inline int __n_counters(void) { 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 +279,9 @@ static inline int n_counters(void) 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 +308,12 @@ static int __init mipsxx_init(void) 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 +329,13 @@ static int __init mipsxx_init(void) 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; @@ -355,6 +371,7 @@ static int __init mipsxx_init(void) return -ENODEV; } + save_perf_irq = perf_irq; perf_irq = mipsxx_perfcount_handler; return 0; @@ -365,9 +382,9 @@ static void mipsxx_exit(void) 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; + perf_irq = save_perf_irq; } struct op_mips_model op_model_mipsxx_ops = { |