aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/time.c')
-rw-r--r--arch/sparc64/kernel/time.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index d457079118dc..48e1217c1e42 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -31,6 +31,7 @@
31#include <linux/profile.h> 31#include <linux/profile.h>
32#include <linux/miscdevice.h> 32#include <linux/miscdevice.h>
33#include <linux/rtc.h> 33#include <linux/rtc.h>
34#include <linux/kernel_stat.h>
34 35
35#include <asm/oplib.h> 36#include <asm/oplib.h>
36#include <asm/mostek.h> 37#include <asm/mostek.h>
@@ -423,12 +424,6 @@ static struct sparc64_tick_ops hbtick_operations __read_mostly = {
423 .softint_mask = 1UL << 0, 424 .softint_mask = 1UL << 0,
424}; 425};
425 426
426/* timer_interrupt() needs to keep up the real-time clock,
427 * as well as call the "do_timer()" routine every clocktick
428 *
429 * NOTE: On SUN5 systems the ticker interrupt comes in using 2
430 * interrupts, one at level14 and one with softint bit 0.
431 */
432unsigned long timer_tick_offset __read_mostly; 427unsigned long timer_tick_offset __read_mostly;
433 428
434static unsigned long timer_ticks_per_nsec_quotient __read_mostly; 429static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
@@ -487,18 +482,27 @@ void notify_arch_cmos_timer(void)
487 mod_timer(&sync_cmos_timer, jiffies + 1); 482 mod_timer(&sync_cmos_timer, jiffies + 1);
488} 483}
489 484
490irqreturn_t timer_interrupt(int irq, void *dev_id) 485void timer_interrupt(int irq, struct pt_regs *regs)
491{ 486{
487 struct pt_regs *old_regs = set_irq_regs(regs);
492 unsigned long ticks, compare, pstate; 488 unsigned long ticks, compare, pstate;
489 unsigned long tick_mask = tick_ops->softint_mask;
490
491 clear_softint(tick_mask);
492
493 irq_enter();
493 494
494 write_seqlock(&xtime_lock); 495 kstat_this_cpu.irqs[0]++;
495 496
496 do { 497 do {
497#ifndef CONFIG_SMP
498 profile_tick(CPU_PROFILING); 498 profile_tick(CPU_PROFILING);
499 update_process_times(user_mode(get_irq_regs())); 499 update_process_times(user_mode(get_irq_regs()));
500#endif 500
501 do_timer(1); 501 if (smp_processor_id() == boot_cpu_id) {
502 write_seqlock(&xtime_lock);
503 do_timer(1);
504 write_sequnlock(&xtime_lock);
505 }
502 506
503 /* Guarantee that the following sequences execute 507 /* Guarantee that the following sequences execute
504 * uninterrupted. 508 * uninterrupted.
@@ -515,24 +519,13 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
515 __asm__ __volatile__("wrpr %0, 0x0, %%pstate" 519 __asm__ __volatile__("wrpr %0, 0x0, %%pstate"
516 : /* no outputs */ 520 : /* no outputs */
517 : "r" (pstate)); 521 : "r" (pstate));
518 } while (time_after_eq(ticks, compare)); 522 } while (unlikely(time_after_eq(ticks, compare)));
519 523
520 write_sequnlock(&xtime_lock); 524 irq_exit();
521 525
522 return IRQ_HANDLED; 526 set_irq_regs(old_regs);
523} 527}
524 528
525#ifdef CONFIG_SMP
526void timer_tick_interrupt(struct pt_regs *regs)
527{
528 write_seqlock(&xtime_lock);
529
530 do_timer(1);
531
532 write_sequnlock(&xtime_lock);
533}
534#endif
535
536/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ 529/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
537static void __init kick_start_clock(void) 530static void __init kick_start_clock(void)
538{ 531{