aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/oprofile/op_model_xscale.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/oprofile/op_model_xscale.c')
-rw-r--r--arch/arm/oprofile/op_model_xscale.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c
index 724ab9ce2526..1d34a02048bd 100644
--- a/arch/arm/oprofile/op_model_xscale.c
+++ b/arch/arm/oprofile/op_model_xscale.c
@@ -17,12 +17,14 @@
17/* #define DEBUG */ 17/* #define DEBUG */
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/err.h>
20#include <linux/sched.h> 21#include <linux/sched.h>
21#include <linux/oprofile.h> 22#include <linux/oprofile.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
23#include <linux/irq.h> 24#include <linux/irq.h>
24 25
25#include <asm/cputype.h> 26#include <asm/cputype.h>
27#include <asm/pmu.h>
26 28
27#include "op_counter.h" 29#include "op_counter.h"
28#include "op_arm_model.h" 30#include "op_arm_model.h"
@@ -33,17 +35,6 @@
33#define PMU_RESET (CCNT_RESET | PMN_RESET) 35#define PMU_RESET (CCNT_RESET | PMN_RESET)
34#define PMU_CNT64 0x008 /* Make CCNT count every 64th cycle */ 36#define PMU_CNT64 0x008 /* Make CCNT count every 64th cycle */
35 37
36/* TODO do runtime detection */
37#ifdef CONFIG_ARCH_IOP32X
38#define XSCALE_PMU_IRQ IRQ_IOP32X_CORE_PMU
39#endif
40#ifdef CONFIG_ARCH_IOP33X
41#define XSCALE_PMU_IRQ IRQ_IOP33X_CORE_PMU
42#endif
43#ifdef CONFIG_ARCH_PXA
44#define XSCALE_PMU_IRQ IRQ_PMU
45#endif
46
47/* 38/*
48 * Different types of events that can be counted by the XScale PMU 39 * Different types of events that can be counted by the XScale PMU
49 * as used by Oprofile userspace. Here primarily for documentation 40 * as used by Oprofile userspace. Here primarily for documentation
@@ -367,6 +358,8 @@ static irqreturn_t xscale_pmu_interrupt(int irq, void *arg)
367 return IRQ_HANDLED; 358 return IRQ_HANDLED;
368} 359}
369 360
361static const struct pmu_irqs *pmu_irqs;
362
370static void xscale_pmu_stop(void) 363static void xscale_pmu_stop(void)
371{ 364{
372 u32 pmnc = read_pmnc(); 365 u32 pmnc = read_pmnc();
@@ -374,20 +367,30 @@ static void xscale_pmu_stop(void)
374 pmnc &= ~PMU_ENABLE; 367 pmnc &= ~PMU_ENABLE;
375 write_pmnc(pmnc); 368 write_pmnc(pmnc);
376 369
377 free_irq(XSCALE_PMU_IRQ, results); 370 free_irq(pmu_irqs->irqs[0], results);
371 release_pmu(pmu_irqs);
372 pmu_irqs = NULL;
378} 373}
379 374
380static int xscale_pmu_start(void) 375static int xscale_pmu_start(void)
381{ 376{
382 int ret; 377 int ret;
383 u32 pmnc = read_pmnc(); 378 u32 pmnc;
379
380 pmu_irqs = reserve_pmu();
381 if (IS_ERR(pmu_irqs))
382 return PTR_ERR(pmu_irqs);
383
384 pmnc = read_pmnc();
384 385
385 ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, IRQF_DISABLED, 386 ret = request_irq(pmu_irqs->irqs[0], xscale_pmu_interrupt,
386 "XScale PMU", (void *)results); 387 IRQF_DISABLED, "XScale PMU", (void *)results);
387 388
388 if (ret < 0) { 389 if (ret < 0) {
389 printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n", 390 printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n",
390 XSCALE_PMU_IRQ); 391 pmu_irqs->irqs[0]);
392 release_pmu(pmu_irqs);
393 pmu_irqs = NULL;
391 return ret; 394 return ret;
392 } 395 }
393 396