diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/sparc/kernel/tick14.c |
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.c | 85 |
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 00000000000..fd8005a3e6b --- /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); + } +} |