diff options
author | Michael Cree <mcree@orcon.net.nz> | 2010-08-09 20:20:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-09 23:45:04 -0400 |
commit | 979f867191f80e74713394cf8c0a3c1b3662b648 (patch) | |
tree | e2483309110e2e285330e7fd2e5f50eb25dced25 /arch/alpha/kernel/time.c | |
parent | 92484f10ca8f7d36f0bfad92b66a20aa03120cc0 (diff) |
alpha: implement HW performance events on the EV67 and later CPUs
This implements hardware performance events for the EV67 and later CPUs
within the Linux performance events subsystem. Only using the performance
monitoring unit in HP/Compaq's so called "Aggregrate mode" is supported.
The code has been implemented in a manner that makes extension to other
older Alpha CPUs relatively straightforward should some mug wish to
indulge themselves.
Signed-off-by: Michael Cree <mcree@orcon.net.nz>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jay Estabrook <jay.estabrook@hp.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha/kernel/time.c')
-rw-r--r-- | arch/alpha/kernel/time.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 1efbed82c0f..eacceb26d9c 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/bcd.h> | 42 | #include <linux/bcd.h> |
43 | #include <linux/profile.h> | 43 | #include <linux/profile.h> |
44 | #include <linux/perf_event.h> | ||
44 | 45 | ||
45 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
@@ -82,6 +83,26 @@ static struct { | |||
82 | 83 | ||
83 | unsigned long est_cycle_freq; | 84 | unsigned long est_cycle_freq; |
84 | 85 | ||
86 | #ifdef CONFIG_PERF_EVENTS | ||
87 | |||
88 | DEFINE_PER_CPU(u8, perf_event_pending); | ||
89 | |||
90 | #define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1 | ||
91 | #define test_perf_event_pending() __get_cpu_var(perf_event_pending) | ||
92 | #define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0 | ||
93 | |||
94 | void set_perf_event_pending(void) | ||
95 | { | ||
96 | set_perf_event_pending_flag(); | ||
97 | } | ||
98 | |||
99 | #else /* CONFIG_PERF_EVENTS */ | ||
100 | |||
101 | #define test_perf_event_pending() 0 | ||
102 | #define clear_perf_event_pending() | ||
103 | |||
104 | #endif /* CONFIG_PERF_EVENTS */ | ||
105 | |||
85 | 106 | ||
86 | static inline __u32 rpcc(void) | 107 | static inline __u32 rpcc(void) |
87 | { | 108 | { |
@@ -175,6 +196,11 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
175 | update_process_times(user_mode(get_irq_regs())); | 196 | update_process_times(user_mode(get_irq_regs())); |
176 | #endif | 197 | #endif |
177 | 198 | ||
199 | if (test_perf_event_pending()) { | ||
200 | clear_perf_event_pending(); | ||
201 | perf_event_do_pending(); | ||
202 | } | ||
203 | |||
178 | return IRQ_HANDLED; | 204 | return IRQ_HANDLED; |
179 | } | 205 | } |
180 | 206 | ||