summaryrefslogtreecommitdiff
path: root/arch/arm/kernel/perf_event.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2011-03-25 13:13:34 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-03-26 10:06:09 +0000
commit574b69cbb633037a9c305d2993aeb680f4a8badd (patch)
tree8fcef55167b8750eeaebffca51b937a993842136 /arch/arm/kernel/perf_event.c
parentd25d3b4c4d0e27975ee659a64b6d29f02fdbfde4 (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.c14
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)
{