aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/oprofile/op_model_v6.c
diff options
context:
space:
mode:
authorJamie Iles <jamie.iles@picochip.com>2010-02-02 20:24:07 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-02-12 17:23:43 +0000
commit1618fdd9602c689de2f820a88cb3e283a39c3d90 (patch)
treebe2cec6548d61dc83b7fc538fa929533f9cb9112 /arch/arm/oprofile/op_model_v6.c
parent0f4f0672ac950c96cffaf84a666d35e817d7c3ca (diff)
ARM: 5901/2: arm/oprofile: reserve the PMU when starting
Make sure that we have access to the performance counters and that they aren't being used by perf events or anything else. Cc: Will Deacon <will.deacon@arm.com> Cc: Jean Pihet <jpihet@mvista.com> Signed-off-by: Jamie Iles <jamie.iles@picochip.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/oprofile/op_model_v6.c')
-rw-r--r--arch/arm/oprofile/op_model_v6.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c
index f7d2ec5ee9a..a22357a2fd0 100644
--- a/arch/arm/oprofile/op_model_v6.c
+++ b/arch/arm/oprofile/op_model_v6.c
@@ -19,39 +19,47 @@
/* #define DEBUG */
#include <linux/types.h>
#include <linux/errno.h>
+#include <linux/err.h>
#include <linux/sched.h>
#include <linux/oprofile.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <asm/system.h>
+#include <asm/pmu.h>
#include "op_counter.h"
#include "op_arm_model.h"
#include "op_model_arm11_core.h"
-static int irqs[] = {
-#ifdef CONFIG_ARCH_OMAP2
- 3,
-#endif
-#ifdef CONFIG_ARCH_BCMRING
- IRQ_PMUIRQ, /* for BCMRING, ARM PMU interrupt is 43 */
-#endif
-};
+static const struct pmu_irqs *pmu_irqs;
static void armv6_pmu_stop(void)
{
arm11_stop_pmu();
- arm11_release_interrupts(irqs, ARRAY_SIZE(irqs));
+ arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+ release_pmu(pmu_irqs);
+ pmu_irqs = NULL;
}
static int armv6_pmu_start(void)
{
int ret;
- ret = arm11_request_interrupts(irqs, ARRAY_SIZE(irqs));
- if (ret >= 0)
+ pmu_irqs = reserve_pmu();
+ if (IS_ERR(pmu_irqs)) {
+ ret = PTR_ERR(pmu_irqs);
+ goto out;
+ }
+
+ ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+ if (ret >= 0) {
ret = arm11_start_pmu();
+ } else {
+ release_pmu(pmu_irqs);
+ pmu_irqs = NULL;
+ }
+out:
return ret;
}