[PATCH 2/4] ARM: perf: Add platform specific start/stop callbacks.
Martin Fuzzey
mfuzzey at parkeon.com
Tue Jul 29 05:33:01 PDT 2014
Some platforms (such as i.MX53) require SOC specific registers
to be manipulated to make the PMU work.
Add callback hooks to support this.
Signed-off-by: Martin Fuzzey <mfuzzey at parkeon.com>
---
arch/arm/include/asm/pmu.h | 9 +++++++++
arch/arm/kernel/perf_event.c | 13 ++++++++++++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 0bd181f..0f361c9 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -15,6 +15,8 @@
#include <linux/interrupt.h>
#include <linux/perf_event.h>
+struct arm_pmu;
+
/*
* struct arm_pmu_platdata - ARM PMU platform data
*
@@ -32,12 +34,18 @@
* succession this handler will only be called following the
* final call to pm_runtime_put() that actually disables the
* hardware.
+ * @start: an optional handler which will be called before starting
+ * the PMU to do any platform specific setup
+ * @stop: an optional handler which be called after stopping the PMU
+ * to do any platform specific teardown
*/
struct arm_pmu_platdata {
irqreturn_t (*handle_irq)(int irq, void *dev,
irq_handler_t pmu_handler);
int (*runtime_resume)(struct device *dev);
int (*runtime_suspend)(struct device *dev);
+ void (*start)(struct arm_pmu *arm_pmu);
+ void (*stop)(struct arm_pmu *arm_pmu);
};
#ifdef CONFIG_HW_PERF_EVENTS
@@ -67,6 +75,7 @@ struct pmu_hw_events {
*/
unsigned int activated_flags;
#define ARM_PMU_ACTIVATED_SECURE_DEBUG (1 << 0)
+ #define ARM_PMU_ACTIVATED_PLATFORM (1 << 1)
};
struct arm_pmu {
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 4238bcb..d0d9a25 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -469,16 +469,27 @@ static void armpmu_enable(struct pmu *pmu)
{
struct arm_pmu *armpmu = to_arm_pmu(pmu);
struct pmu_hw_events *hw_events = armpmu->get_hw_events();
+ struct arm_pmu_platdata *plat =
+ dev_get_platdata(&armpmu->plat_device->dev);
+
int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
- if (enabled)
+ if (enabled) {
+ if (plat && plat->start)
+ plat->start(armpmu);
armpmu->start(armpmu);
+ }
}
static void armpmu_disable(struct pmu *pmu)
{
struct arm_pmu *armpmu = to_arm_pmu(pmu);
+ struct arm_pmu_platdata *plat =
+ dev_get_platdata(&armpmu->plat_device->dev);
+
armpmu->stop(armpmu);
+ if (plat && plat->stop)
+ plat->stop(armpmu);
}
#ifdef CONFIG_PM_RUNTIME
More information about the linux-arm-kernel
mailing list