summary refs log tree commit diff
path: root/arch/sparc/kernel/tick14.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sparc/kernel/tick14.c
downloadlinux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
Diffstat (limited to 'arch/sparc/kernel/tick14.c')
-rw-r--r--arch/sparc/kernel/tick14.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/arch/sparc/kernel/tick14.c b/arch/sparc/kernel/tick14.c
new file mode 100644
index 000000000000..fd8005a3e6bd
--- /dev/null
+++ b/arch/sparc/kernel/tick14.c
@@ -0,0 +1,85 @@
+/* tick14.c
+ * linux/arch/sparc/kernel/tick14.c
+ *
+ * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
+ *
+ * This file handles the Sparc specific level14 ticker
+ * This is really useful for profiling OBP uses it for keyboard
+ * aborts and other stuff.
+ *
+ *
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/timex.h>
+#include <linux/interrupt.h>
+
+#include <asm/oplib.h>
+#include <asm/segment.h>
+#include <asm/timer.h>
+#include <asm/mostek.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+extern unsigned long lvl14_save[5];
+static unsigned long *linux_lvl14 = NULL;
+static unsigned long obp_lvl14[4];
+ 
+/*
+ * Call with timer IRQ closed.
+ * First time we do it with disable_irq, later prom code uses spin_lock_irq().
+ */
+void install_linux_ticker(void)
+{
+
+	if (!linux_lvl14)
+		return;
+	linux_lvl14[0] =  lvl14_save[0];
+	linux_lvl14[1] =  lvl14_save[1];
+	linux_lvl14[2] =  lvl14_save[2];
+	linux_lvl14[3] =  lvl14_save[3];
+}
+
+void install_obp_ticker(void)
+{
+
+	if (!linux_lvl14)
+		return;
+	linux_lvl14[0] =  obp_lvl14[0];
+	linux_lvl14[1] =  obp_lvl14[1];
+	linux_lvl14[2] =  obp_lvl14[2];
+	linux_lvl14[3] =  obp_lvl14[3]; 
+}
+
+void claim_ticker14(irqreturn_t (*handler)(int, void *, struct pt_regs *),
+		    int irq_nr, unsigned int timeout )
+{
+	int cpu = smp_processor_id();
+
+	/* first we copy the obp handler instructions
+	 */
+	disable_irq(irq_nr);
+	if (!handler)
+		return;
+    
+	linux_lvl14 = (unsigned long *)lvl14_save[4];
+	obp_lvl14[0] = linux_lvl14[0];
+	obp_lvl14[1] = linux_lvl14[1];
+	obp_lvl14[2] = linux_lvl14[2];
+	obp_lvl14[3] = linux_lvl14[3];
+
+	if (!request_irq(irq_nr,
+			 handler,
+			 (SA_INTERRUPT | SA_STATIC_ALLOC),
+			 "counter14",
+			 NULL)) {
+		install_linux_ticker();
+		load_profile_irq(cpu, timeout);
+		enable_irq(irq_nr);
+	}
+}