aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2011-05-19 05:07:57 -0400
committerWill Deacon <will.deacon@arm.com>2011-08-31 05:50:13 -0400
commit0ce47080dfffe71edd433b35dcdada24c61079eb (patch)
tree93b84dc2cbfae0cb4dd59450a880db2c742b4117
parent8be3f9a2385f91f7bf5c58f351e24b9247898e8f (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.h64
-rw-r--r--arch/arm/kernel/perf_event.c53
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. */
86struct 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
105struct 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
134int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type);
135
136u64 armpmu_event_update(struct perf_event *event,
137 struct hw_perf_event *hwc,
138 int idx, int overflow);
139
140int 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. */
41struct 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
60static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); 40static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
61static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); 41static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
62static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); 42static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
63 43
64struct 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
197static int 150int
198armpmu_event_set_period(struct perf_event *event, 151armpmu_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
233static u64 186u64
234armpmu_event_update(struct perf_event *event, 187armpmu_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
649static int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) 602int __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);