diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 5fb8f5c18080b1f6d754730727179406f70c4c54..f4fbf11804da239cac593a0c0a70d2e50db4a04b 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -946,113 +946,6 @@ int probe_irq_off(unsigned long mask) return 0; } -/* This is gets the master TICK_INT timer going. */ -void sparc64_init_timers(void (*cfunc)(int, void *, struct pt_regs *), - unsigned long *clock) -{ - unsigned long pstate; - extern unsigned long timer_tick_offset; - int node, err; -#ifdef CONFIG_SMP - extern void smp_tick_init(void); -#endif - - if (!SPARC64_USE_STICK) { - node = linux_cpus[0].prom_node; - *clock = prom_getint(node, "clock-frequency"); - } else { - node = prom_root_node; - *clock = prom_getint(node, "stick-frequency"); - } - timer_tick_offset = *clock / HZ; -#ifdef CONFIG_SMP - smp_tick_init(); -#endif - - /* Register IRQ handler. */ - err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC, - "timer", NULL); - - if (err) { - prom_printf("Serious problem, cannot register TICK_INT\n"); - prom_halt(); - } - - /* Guarentee that the following sequences execute - * uninterrupted. - */ - __asm__ __volatile__("rdpr %%pstate, %0\n\t" - "wrpr %0, %1, %%pstate" - : "=r" (pstate) - : "i" (PSTATE_IE)); - - /* Set things up so user can access tick register for profiling - * purposes. Also workaround BB_ERRATA_1 by doing a dummy - * read back of %tick after writing it. - */ - __asm__ __volatile__( - " sethi %%hi(0x80000000), %%g1\n" - " ba,pt %%xcc, 1f\n" - " sllx %%g1, 32, %%g1\n" - " .align 64\n" - "1: rd %%tick, %%g2\n" - " add %%g2, 6, %%g2\n" - " andn %%g2, %%g1, %%g2\n" - " wrpr %%g2, 0, %%tick\n" - " rdpr %%tick, %%g0" - : /* no outputs */ - : /* no inputs */ - : "g1", "g2"); - - /* Workaround for Spitfire Errata (#54 I think??), I discovered - * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch - * number 103640. - * - * On Blackbird writes to %tick_cmpr can fail, the - * workaround seems to be to execute the wr instruction - * at the start of an I-cache line, and perform a dummy - * read back from %tick_cmpr right after writing to it. -DaveM - */ - if (!SPARC64_USE_STICK) { - __asm__ __volatile__( - " rd %%tick, %%g1\n" - " ba,pt %%xcc, 1f\n" - " add %%g1, %0, %%g1\n" - " .align 64\n" - "1: wr %%g1, 0x0, %%tick_cmpr\n" - " rd %%tick_cmpr, %%g0" - : /* no outputs */ - : "r" (timer_tick_offset) - : "g1"); - } else { - /* Let the user get at STICK too. */ - __asm__ __volatile__( - " sethi %%hi(0x80000000), %%g1\n" - " sllx %%g1, 32, %%g1\n" - " rd %%asr24, %%g2\n" - " andn %%g2, %%g1, %%g2\n" - " wr %%g2, 0, %%asr24" - : /* no outputs */ - : /* no inputs */ - : "g1", "g2"); - - __asm__ __volatile__( - " rd %%asr24, %%g1\n" - " add %%g1, %0, %%g1\n" - " wr %%g1, 0x0, %%asr25" - : /* no outputs */ - : "r" (timer_tick_offset) - : "g1"); - } - - /* Restore PSTATE_IE. */ - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" - : /* no outputs */ - : "r" (pstate)); - - local_irq_enable(); -} - #ifdef CONFIG_SMP static int retarget_one_irq(struct irqaction *p, int goal_cpu) { diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 7503513d4bdc319c078ca42fa1e5c9a31ebba60d..dba2283e9686e33d97357dd53c7a92565f685254 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -620,6 +620,113 @@ void __init clock_probe(void) local_irq_restore(flags); } +/* This is gets the master TICK_INT timer going. */ +static void sparc64_init_timers(void (*cfunc)(int, void *, struct pt_regs *), + unsigned long *clock) +{ + unsigned long pstate; + extern unsigned long timer_tick_offset; + int node, err; +#ifdef CONFIG_SMP + extern void smp_tick_init(void); +#endif + + if (!SPARC64_USE_STICK) { + node = linux_cpus[0].prom_node; + *clock = prom_getint(node, "clock-frequency"); + } else { + node = prom_root_node; + *clock = prom_getint(node, "stick-frequency"); + } + timer_tick_offset = *clock / HZ; +#ifdef CONFIG_SMP + smp_tick_init(); +#endif + + /* Register IRQ handler. */ + err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC, + "timer", NULL); + + if (err) { + prom_printf("Serious problem, cannot register TICK_INT\n"); + prom_halt(); + } + + /* Guarentee that the following sequences execute + * uninterrupted. + */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + /* Set things up so user can access tick register for profiling + * purposes. Also workaround BB_ERRATA_1 by doing a dummy + * read back of %tick after writing it. + */ + __asm__ __volatile__( + " sethi %%hi(0x80000000), %%g1\n" + " ba,pt %%xcc, 1f\n" + " sllx %%g1, 32, %%g1\n" + " .align 64\n" + "1: rd %%tick, %%g2\n" + " add %%g2, 6, %%g2\n" + " andn %%g2, %%g1, %%g2\n" + " wrpr %%g2, 0, %%tick\n" + " rdpr %%tick, %%g0" + : /* no outputs */ + : /* no inputs */ + : "g1", "g2"); + + /* Workaround for Spitfire Errata (#54 I think??), I discovered + * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch + * number 103640. + * + * On Blackbird writes to %tick_cmpr can fail, the + * workaround seems to be to execute the wr instruction + * at the start of an I-cache line, and perform a dummy + * read back from %tick_cmpr right after writing to it. -DaveM + */ + if (!SPARC64_USE_STICK) { + __asm__ __volatile__( + " rd %%tick, %%g1\n" + " ba,pt %%xcc, 1f\n" + " add %%g1, %0, %%g1\n" + " .align 64\n" + "1: wr %%g1, 0x0, %%tick_cmpr\n" + " rd %%tick_cmpr, %%g0" + : /* no outputs */ + : "r" (timer_tick_offset) + : "g1"); + } else { + /* Let the user get at STICK too. */ + __asm__ __volatile__( + " sethi %%hi(0x80000000), %%g1\n" + " sllx %%g1, 32, %%g1\n" + " rd %%asr24, %%g2\n" + " andn %%g2, %%g1, %%g2\n" + " wr %%g2, 0, %%asr24" + : /* no outputs */ + : /* no inputs */ + : "g1", "g2"); + + __asm__ __volatile__( + " rd %%asr24, %%g1\n" + " add %%g1, %0, %%g1\n" + " wr %%g1, 0x0, %%asr25" + : /* no outputs */ + : "r" (timer_tick_offset) + : "g1"); + } + + /* Restore PSTATE_IE. */ + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : /* no outputs */ + : "r" (pstate)); + + local_irq_enable(); +} + void __init time_init(void) { /* clock_probe() is now done at end of [se]bus_init on sparc64 diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index f2423a38eee4b2677f6d9c4f69b78ba75b163c4d..f708a38bf79ea18ea8ddeade34847208df8bd011 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -117,8 +117,6 @@ static __inline__ char *__irq_itoa(unsigned int irq) extern void disable_irq(unsigned int); #define disable_irq_nosync disable_irq extern void enable_irq(unsigned int); -extern void sparc64_init_timers(void (*lvl10_irq)(int, void *, struct pt_regs *), - unsigned long *); extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); extern unsigned int psycho_build_irq(void *psycho, int imap_off, int ino, int need_dma_sync);