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.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 774c0a3c5019..a124499e65d9 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -125,15 +125,8 @@ static long timezone_offset;
125unsigned long ppc_proc_freq; 125unsigned long ppc_proc_freq;
126unsigned long ppc_tb_freq; 126unsigned long ppc_tb_freq;
127 127
128u64 tb_last_jiffy __cacheline_aligned_in_smp; 128static u64 tb_last_jiffy __cacheline_aligned_in_smp;
129unsigned long tb_last_stamp; 129static DEFINE_PER_CPU(u64, last_jiffy);
130
131/*
132 * Note that on ppc32 this only stores the bottom 32 bits of
133 * the timebase value, but that's enough to tell when a jiffy
134 * has passed.
135 */
136DEFINE_PER_CPU(unsigned long, last_jiffy);
137 130
138#ifdef CONFIG_VIRT_CPU_ACCOUNTING 131#ifdef CONFIG_VIRT_CPU_ACCOUNTING
139/* 132/*
@@ -417,7 +410,7 @@ static __inline__ void timer_check_rtc(void)
417/* 410/*
418 * This version of gettimeofday has microsecond resolution. 411 * This version of gettimeofday has microsecond resolution.
419 */ 412 */
420static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val) 413static inline void __do_gettimeofday(struct timeval *tv)
421{ 414{
422 unsigned long sec, usec; 415 unsigned long sec, usec;
423 u64 tb_ticks, xsec; 416 u64 tb_ticks, xsec;
@@ -431,7 +424,12 @@ static inline void __do_gettimeofday(struct timeval *tv, u64 tb_val)
431 * without a divide (and in fact, without a multiply) 424 * without a divide (and in fact, without a multiply)
432 */ 425 */
433 temp_varp = do_gtod.varp; 426 temp_varp = do_gtod.varp;
434 tb_ticks = tb_val - temp_varp->tb_orig_stamp; 427
428 /* Sampling the time base must be done after loading
429 * do_gtod.varp in order to avoid racing with update_gtod.
430 */
431 data_barrier(temp_varp);
432 tb_ticks = get_tb() - temp_varp->tb_orig_stamp;
435 temp_tb_to_xs = temp_varp->tb_to_xs; 433 temp_tb_to_xs = temp_varp->tb_to_xs;
436 temp_stamp_xsec = temp_varp->stamp_xsec; 434 temp_stamp_xsec = temp_varp->stamp_xsec;
437 xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs); 435 xsec = temp_stamp_xsec + mulhdu(tb_ticks, temp_tb_to_xs);
@@ -453,7 +451,7 @@ void do_gettimeofday(struct timeval *tv)
453 do { 451 do {
454 seq = read_seqbegin_irqsave(&xtime_lock, flags); 452 seq = read_seqbegin_irqsave(&xtime_lock, flags);
455 sec = xtime.tv_sec; 453 sec = xtime.tv_sec;
456 nsec = xtime.tv_nsec + tb_ticks_since(tb_last_stamp); 454 nsec = xtime.tv_nsec + tb_ticks_since(tb_last_jiffy);
457 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); 455 } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
458 usec = nsec / 1000; 456 usec = nsec / 1000;
459 while (usec >= 1000000) { 457 while (usec >= 1000000) {
@@ -464,7 +462,7 @@ void do_gettimeofday(struct timeval *tv)
464 tv->tv_usec = usec; 462 tv->tv_usec = usec;
465 return; 463 return;
466 } 464 }
467 __do_gettimeofday(tv, get_tb()); 465 __do_gettimeofday(tv);
468} 466}
469 467
470EXPORT_SYMBOL(do_gettimeofday); 468EXPORT_SYMBOL(do_gettimeofday);
@@ -650,6 +648,7 @@ void timer_interrupt(struct pt_regs * regs)
650 int next_dec; 648 int next_dec;
651 int cpu = smp_processor_id(); 649 int cpu = smp_processor_id();
652 unsigned long ticks; 650 unsigned long ticks;
651 u64 tb_next_jiffy;
653 652
654#ifdef CONFIG_PPC32 653#ifdef CONFIG_PPC32
655 if (atomic_read(&ppc_n_lost_interrupts) != 0) 654 if (atomic_read(&ppc_n_lost_interrupts) != 0)
@@ -691,11 +690,13 @@ void timer_interrupt(struct pt_regs * regs)
691 continue; 690 continue;
692 691
693 write_seqlock(&xtime_lock); 692 write_seqlock(&xtime_lock);
694 tb_last_jiffy += tb_ticks_per_jiffy; 693 tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy;
695 tb_last_stamp = per_cpu(last_jiffy, cpu); 694 if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) {
696 do_timer(regs); 695 tb_last_jiffy = tb_next_jiffy;
697 timer_recalc_offset(tb_last_jiffy); 696 do_timer(regs);
698 timer_check_rtc(); 697 timer_recalc_offset(tb_last_jiffy);
698 timer_check_rtc();
699 }
699 write_sequnlock(&xtime_lock); 700 write_sequnlock(&xtime_lock);
700 } 701 }
701 702
@@ -740,7 +741,7 @@ void __init smp_space_timers(unsigned int max_cpus)
740 int i; 741 int i;
741 unsigned long half = tb_ticks_per_jiffy / 2; 742 unsigned long half = tb_ticks_per_jiffy / 2;
742 unsigned long offset = tb_ticks_per_jiffy / max_cpus; 743 unsigned long offset = tb_ticks_per_jiffy / max_cpus;
743 unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid); 744 u64 previous_tb = per_cpu(last_jiffy, boot_cpuid);
744 745
745 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */ 746 /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
746 previous_tb -= tb_ticks_per_jiffy; 747 previous_tb -= tb_ticks_per_jiffy;
@@ -821,7 +822,7 @@ int do_settimeofday(struct timespec *tv)
821 * and therefore the (jiffies - wall_jiffies) computation 822 * and therefore the (jiffies - wall_jiffies) computation
822 * has been removed. 823 * has been removed.
823 */ 824 */
824 tb_delta = tb_ticks_since(tb_last_stamp); 825 tb_delta = tb_ticks_since(tb_last_jiffy);
825 tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ 826 tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */
826 new_nsec -= SCALE_XSEC(tb_delta, 1000000000); 827 new_nsec -= SCALE_XSEC(tb_delta, 1000000000);
827 828
@@ -941,8 +942,7 @@ void __init time_init(void)
941 if (__USE_RTC()) { 942 if (__USE_RTC()) {
942 /* 601 processor: dec counts down by 128 every 128ns */ 943 /* 601 processor: dec counts down by 128 every 128ns */
943 ppc_tb_freq = 1000000000; 944 ppc_tb_freq = 1000000000;
944 tb_last_stamp = get_rtcl(); 945 tb_last_jiffy = get_rtcl();
945 tb_last_jiffy = tb_last_stamp;
946 } else { 946 } else {
947 /* Normal PowerPC with timebase register */ 947 /* Normal PowerPC with timebase register */
948 ppc_md.calibrate_decr(); 948 ppc_md.calibrate_decr();
@@ -950,7 +950,7 @@ void __init time_init(void)
950 ppc_tb_freq / 1000000, ppc_tb_freq % 1000000); 950 ppc_tb_freq / 1000000, ppc_tb_freq % 1000000);
951 printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n", 951 printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n",
952 ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); 952 ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
953 tb_last_stamp = tb_last_jiffy = get_tb(); 953 tb_last_jiffy = get_tb();
954 } 954 }
955 955
956 tb_ticks_per_jiffy = ppc_tb_freq / HZ; 956 tb_ticks_per_jiffy = ppc_tb_freq / HZ;
@@ -1027,7 +1027,7 @@ void __init time_init(void)
1027 do_gtod.varp = &do_gtod.vars[0]; 1027 do_gtod.varp = &do_gtod.vars[0];
1028 do_gtod.var_idx = 0; 1028 do_gtod.var_idx = 0;
1029 do_gtod.varp->tb_orig_stamp = tb_last_jiffy; 1029 do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
1030 __get_cpu_var(last_jiffy) = tb_last_stamp; 1030 __get_cpu_var(last_jiffy) = tb_last_jiffy;
1031 do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; 1031 do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
1032 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; 1032 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
1033 do_gtod.varp->tb_to_xs = tb_to_xs; 1033 do_gtod.varp->tb_to_xs = tb_to_xs;