diff options
author | Mark Rutland <mark.rutland@arm.com> | 2011-05-19 05:07:57 -0400 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2011-08-31 05:50:13 -0400 |
commit | 0ce47080dfffe71edd433b35dcdada24c61079eb (patch) | |
tree | 93b84dc2cbfae0cb4dd59450a880db2c742b4117 | |
parent | 8be3f9a2385f91f7bf5c58f351e24b9247898e8f (diff) |
ARM: perf: move arm_pmu into <asm/pmu.h>
Currently, struct arm_pmu and related functions are only visible to
{,arch/arm/}/kernel/perf_event.c. This prevents new drivers from using
the framework.
This patch moves declarations to asm/pmu.h, allowing new PMU drivers
to use the framework.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Jamie Iles <jamie@jamieiles.com>
Reviewed-by: Ashwin Chaugule <ashwinc@codeaurora.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r-- | arch/arm/include/asm/pmu.h | 64 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event.c | 53 |
2 files changed, 67 insertions, 50 deletions
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index a06ba8773cd7..71d99b83cdb9 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define __ARM_PMU_H__ | 13 | #define __ARM_PMU_H__ |
14 | 14 | ||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/perf_event.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * Types of PMUs that can be accessed directly and require mutual | 19 | * Types of PMUs that can be accessed directly and require mutual |
@@ -79,4 +80,67 @@ release_pmu(enum arm_pmu_type type) { } | |||
79 | 80 | ||
80 | #endif /* CONFIG_CPU_HAS_PMU */ | 81 | #endif /* CONFIG_CPU_HAS_PMU */ |
81 | 82 | ||
83 | #ifdef CONFIG_HW_PERF_EVENTS | ||
84 | |||
85 | /* The events for a given PMU register set. */ | ||
86 | struct pmu_hw_events { | ||
87 | /* | ||
88 | * The events that are active on the PMU for the given index. | ||
89 | */ | ||
90 | struct perf_event **events; | ||
91 | |||
92 | /* | ||
93 | * A 1 bit for an index indicates that the counter is being used for | ||
94 | * an event. A 0 means that the counter can be used. | ||
95 | */ | ||
96 | unsigned long *used_mask; | ||
97 | |||
98 | /* | ||
99 | * Hardware lock to serialize accesses to PMU registers. Needed for the | ||
100 | * read/modify/write sequences. | ||
101 | */ | ||
102 | raw_spinlock_t pmu_lock; | ||
103 | }; | ||
104 | |||
105 | struct arm_pmu { | ||
106 | struct pmu pmu; | ||
107 | enum arm_perf_pmu_ids id; | ||
108 | enum arm_pmu_type type; | ||
109 | cpumask_t active_irqs; | ||
110 | const char *name; | ||
111 | irqreturn_t (*handle_irq)(int irq_num, void *dev); | ||
112 | void (*enable)(struct hw_perf_event *evt, int idx); | ||
113 | void (*disable)(struct hw_perf_event *evt, int idx); | ||
114 | int (*get_event_idx)(struct pmu_hw_events *hw_events, | ||
115 | struct hw_perf_event *hwc); | ||
116 | int (*set_event_filter)(struct hw_perf_event *evt, | ||
117 | struct perf_event_attr *attr); | ||
118 | u32 (*read_counter)(int idx); | ||
119 | void (*write_counter)(int idx, u32 val); | ||
120 | void (*start)(void); | ||
121 | void (*stop)(void); | ||
122 | void (*reset)(void *); | ||
123 | int (*map_event)(struct perf_event *event); | ||
124 | int num_events; | ||
125 | atomic_t active_events; | ||
126 | struct mutex reserve_mutex; | ||
127 | u64 max_period; | ||
128 | struct platform_device *plat_device; | ||
129 | struct pmu_hw_events *(*get_hw_events)(void); | ||
130 | }; | ||
131 | |||
132 | #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) | ||
133 | |||
134 | int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type); | ||
135 | |||
136 | u64 armpmu_event_update(struct perf_event *event, | ||
137 | struct hw_perf_event *hwc, | ||
138 | int idx, int overflow); | ||
139 | |||
140 | int armpmu_event_set_period(struct perf_event *event, | ||
141 | struct hw_perf_event *hwc, | ||
142 | int idx); | ||
143 | |||
144 | #endif /* CONFIG_HW_PERF_EVENTS */ | ||
145 | |||
82 | #endif /* __ARM_PMU_H__ */ | 146 | #endif /* __ARM_PMU_H__ */ |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 831513342d53..aaa631b8cbc2 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -37,57 +37,10 @@ | |||
37 | */ | 37 | */ |
38 | #define ARMPMU_MAX_HWEVENTS 32 | 38 | #define ARMPMU_MAX_HWEVENTS 32 |
39 | 39 | ||
40 | /* The events for a given PMU register set. */ | ||
41 | struct pmu_hw_events { | ||
42 | /* | ||
43 | * The events that are active on the PMU for the given index. | ||
44 | */ | ||
45 | struct perf_event **events; | ||
46 | |||
47 | /* | ||
48 | * A 1 bit for an index indicates that the counter is being used for | ||
49 | * an event. A 0 means that the counter can be used. | ||
50 | */ | ||
51 | unsigned long *used_mask; | ||
52 | |||
53 | /* | ||
54 | * Hardware lock to serialize accesses to PMU registers. Needed for the | ||
55 | * read/modify/write sequences. | ||
56 | */ | ||
57 | raw_spinlock_t pmu_lock; | ||
58 | }; | ||
59 | |||
60 | static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); | 40 | static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); |
61 | static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); | 41 | static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); |
62 | static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); | 42 | static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); |
63 | 43 | ||
64 | struct arm_pmu { | ||
65 | struct pmu pmu; | ||
66 | enum arm_perf_pmu_ids id; | ||
67 | enum arm_pmu_type type; | ||
68 | cpumask_t active_irqs; | ||
69 | const char *name; | ||
70 | irqreturn_t (*handle_irq)(int irq_num, void *dev); | ||
71 | void (*enable)(struct hw_perf_event *evt, int idx); | ||
72 | void (*disable)(struct hw_perf_event *evt, int idx); | ||
73 | int (*get_event_idx)(struct pmu_hw_events *hw_events, | ||
74 | struct hw_perf_event *hwc); | ||
75 | int (*set_event_filter)(struct hw_perf_event *evt, | ||
76 | struct perf_event_attr *attr); | ||
77 | u32 (*read_counter)(int idx); | ||
78 | void (*write_counter)(int idx, u32 val); | ||
79 | void (*start)(void); | ||
80 | void (*stop)(void); | ||
81 | void (*reset)(void *); | ||
82 | int (*map_event)(struct perf_event *event); | ||
83 | int num_events; | ||
84 | atomic_t active_events; | ||
85 | struct mutex reserve_mutex; | ||
86 | u64 max_period; | ||
87 | struct platform_device *plat_device; | ||
88 | struct pmu_hw_events *(*get_hw_events)(void); | ||
89 | }; | ||
90 | |||
91 | #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) | 44 | #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) |
92 | 45 | ||
93 | /* Set at runtime when we know what CPU type we are. */ | 46 | /* Set at runtime when we know what CPU type we are. */ |
@@ -194,7 +147,7 @@ static int map_cpu_event(struct perf_event *event, | |||
194 | return -ENOENT; | 147 | return -ENOENT; |
195 | } | 148 | } |
196 | 149 | ||
197 | static int | 150 | int |
198 | armpmu_event_set_period(struct perf_event *event, | 151 | armpmu_event_set_period(struct perf_event *event, |
199 | struct hw_perf_event *hwc, | 152 | struct hw_perf_event *hwc, |
200 | int idx) | 153 | int idx) |
@@ -230,7 +183,7 @@ armpmu_event_set_period(struct perf_event *event, | |||
230 | return ret; | 183 | return ret; |
231 | } | 184 | } |
232 | 185 | ||
233 | static u64 | 186 | u64 |
234 | armpmu_event_update(struct perf_event *event, | 187 | armpmu_event_update(struct perf_event *event, |
235 | struct hw_perf_event *hwc, | 188 | struct hw_perf_event *hwc, |
236 | int idx, int overflow) | 189 | int idx, int overflow) |
@@ -646,7 +599,7 @@ static void __init armpmu_init(struct arm_pmu *armpmu) | |||
646 | }; | 599 | }; |
647 | } | 600 | } |
648 | 601 | ||
649 | static int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) | 602 | int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) |
650 | { | 603 | { |
651 | armpmu_init(armpmu); | 604 | armpmu_init(armpmu); |
652 | return perf_pmu_register(&armpmu->pmu, name, type); | 605 | return perf_pmu_register(&armpmu->pmu, name, type); |