diff options
author | Will Deacon <will.deacon@arm.com> | 2011-03-25 13:13:34 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-03-26 10:06:09 +0000 |
commit | 574b69cbb633037a9c305d2993aeb680f4a8badd (patch) | |
tree | 8fcef55167b8750eeaebffca51b937a993842136 /arch/arm/kernel/perf_event.c | |
parent | d25d3b4c4d0e27975ee659a64b6d29f02fdbfde4 (diff) |
ARM: 6834/1: perf: reset counters on all CPUs during initialisation
ARMv7 dictates that the interrupt-enable and count-enable registers for
each PMU counter are UNKNOWN following core reset.
This patch adds a new (optional) function pointer to struct arm_pmu for
resetting the PMU state during init. The reset function is called on
each CPU via an arch_initcall in the generic ARM perf_event code and
allows the PMU backend to write sane values to any UNKNOWN registers.
Acked-by: Jean Pihet <j-pihet@ti.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/perf_event.c')
-rw-r--r-- | arch/arm/kernel/perf_event.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 22e194eb8536..e422f4c269a0 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -79,6 +79,7 @@ struct arm_pmu { void (*write_counter)(int idx, u32 val); void (*start)(void); void (*stop)(void); + void (*reset)(void *); const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX]; @@ -624,6 +625,19 @@ static struct pmu pmu = { #include "perf_event_v6.c" #include "perf_event_v7.c" +/* + * Ensure the PMU has sane values out of reset. + * This requires SMP to be available, so exists as a separate initcall. + */ +static int __init +armpmu_reset(void) +{ + if (armpmu && armpmu->reset) + return on_each_cpu(armpmu->reset, NULL, 1); + return 0; +} +arch_initcall(armpmu_reset); + static int __init init_hw_perf_events(void) { |