diff options
Diffstat (limited to 'arch/arm/oprofile/op_model_xscale.c')
-rw-r--r-- | arch/arm/oprofile/op_model_xscale.c | 35 |
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 | ||
361 | static const struct pmu_irqs *pmu_irqs; | ||
362 | |||
370 | static void xscale_pmu_stop(void) | 363 | static 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 | ||
380 | static int xscale_pmu_start(void) | 375 | static 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 | ||