alpha: implement HW performance events on the EV67 and later CPUs
[sfrench/cifs-2.6.git] / arch / alpha / kernel / time.c
index 1efbed82c0fd38a2bb0ecd925d80bef884801642..eacceb26d9c8aa8bd250b409e821c277a9b51c73 100644 (file)
@@ -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;
 }