summaryrefslogtreecommitdiffstats
path: root/arch/alpha/kernel/time.c
diff options
context:
space:
mode:
authorMichael Cree <mcree@orcon.net.nz>2010-08-09 17:20:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-09 20:45:04 -0700
commit979f867191f80e74713394cf8c0a3c1b3662b648 (patch)
treee2483309110e2e285330e7fd2e5f50eb25dced25 /arch/alpha/kernel/time.c
parent92484f10ca8f7d36f0bfad92b66a20aa03120cc0 (diff)
downloadlinux-979f867191f80e74713394cf8c0a3c1b3662b648.tar.bz2
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.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 1efbed82c0fd..eacceb26d9c8 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -41,6 +41,7 @@
#include <linux/init.h>
#include <linux/bcd.h>
#include <linux/profile.h>
+#include <linux/perf_event.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -82,6 +83,26 @@ static struct {
unsigned long est_cycle_freq;
+#ifdef CONFIG_PERF_EVENTS
+
+DEFINE_PER_CPU(u8, perf_event_pending);
+
+#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1
+#define test_perf_event_pending() __get_cpu_var(perf_event_pending)
+#define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0
+
+void set_perf_event_pending(void)
+{
+ set_perf_event_pending_flag();
+}
+
+#else /* CONFIG_PERF_EVENTS */
+
+#define test_perf_event_pending() 0
+#define clear_perf_event_pending()
+
+#endif /* CONFIG_PERF_EVENTS */
+
static inline __u32 rpcc(void)
{
@@ -175,6 +196,11 @@ irqreturn_t timer_interrupt(int irq, void *dev)
update_process_times(user_mode(get_irq_regs()));
#endif
+ if (test_perf_event_pending()) {
+ clear_perf_event_pending();
+ perf_event_do_pending();
+ }
+
return IRQ_HANDLED;
}