aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r--arch/powerpc/kernel/time.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index d20947cf1735..9368da371f36 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -108,7 +108,7 @@ static void decrementer_set_mode(enum clock_event_mode mode,
108static struct clock_event_device decrementer_clockevent = { 108static struct clock_event_device decrementer_clockevent = {
109 .name = "decrementer", 109 .name = "decrementer",
110 .rating = 200, 110 .rating = 200,
111 .shift = 32, 111 .shift = 16,
112 .mult = 0, /* To be filled in */ 112 .mult = 0, /* To be filled in */
113 .irq = 0, 113 .irq = 0,
114 .set_next_event = decrementer_set_next_event, 114 .set_next_event = decrementer_set_next_event,
@@ -118,6 +118,7 @@ static struct clock_event_device decrementer_clockevent = {
118 118
119static DEFINE_PER_CPU(struct clock_event_device, decrementers); 119static DEFINE_PER_CPU(struct clock_event_device, decrementers);
120void init_decrementer_clockevent(void); 120void init_decrementer_clockevent(void);
121static DEFINE_PER_CPU(u64, decrementer_next_tb);
121 122
122#ifdef CONFIG_PPC_ISERIES 123#ifdef CONFIG_PPC_ISERIES
123static unsigned long __initdata iSeries_recal_titan; 124static unsigned long __initdata iSeries_recal_titan;
@@ -541,6 +542,7 @@ void timer_interrupt(struct pt_regs * regs)
541 struct pt_regs *old_regs; 542 struct pt_regs *old_regs;
542 int cpu = smp_processor_id(); 543 int cpu = smp_processor_id();
543 struct clock_event_device *evt = &per_cpu(decrementers, cpu); 544 struct clock_event_device *evt = &per_cpu(decrementers, cpu);
545 u64 now;
544 546
545 /* Ensure a positive value is written to the decrementer, or else 547 /* Ensure a positive value is written to the decrementer, or else
546 * some CPUs will continuue to take decrementer exceptions */ 548 * some CPUs will continuue to take decrementer exceptions */
@@ -551,6 +553,14 @@ void timer_interrupt(struct pt_regs * regs)
551 do_IRQ(regs); 553 do_IRQ(regs);
552#endif 554#endif
553 555
556 now = get_tb_or_rtc();
557 if (now < per_cpu(decrementer_next_tb, cpu)) {
558 /* not time for this event yet */
559 now = per_cpu(decrementer_next_tb, cpu) - now;
560 if (now <= DECREMENTER_MAX)
561 set_dec((unsigned int)now - 1);
562 return;
563 }
554 old_regs = set_irq_regs(regs); 564 old_regs = set_irq_regs(regs);
555 irq_enter(); 565 irq_enter();
556 566
@@ -797,6 +807,10 @@ void __init clocksource_init(void)
797static int decrementer_set_next_event(unsigned long evt, 807static int decrementer_set_next_event(unsigned long evt,
798 struct clock_event_device *dev) 808 struct clock_event_device *dev)
799{ 809{
810 __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt;
811 /* The decrementer interrupts on the 0 -> -1 transition */
812 if (evt)
813 --evt;
800 set_dec(evt); 814 set_dec(evt);
801 return 0; 815 return 0;
802} 816}