]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/kernel/time.c
Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6-omap-h63xx.git] / arch / powerpc / kernel / time.c
index a6282b625b440203aebb48f58e59c10fb4fa1ed5..c4a294d657b92c23eee484902e6a963e4e0f3ab5 100644 (file)
@@ -62,8 +62,8 @@
 #include <asm/irq.h>
 #include <asm/div64.h>
 #include <asm/smp.h>
+#include <asm/vdso_datapage.h>
 #ifdef CONFIG_PPC64
-#include <asm/systemcfg.h>
 #include <asm/firmware.h>
 #endif
 #ifdef CONFIG_PPC_ISERIES
@@ -130,6 +130,34 @@ unsigned long tb_last_stamp;
  */
 DEFINE_PER_CPU(unsigned long, last_jiffy);
 
+void __delay(unsigned long loops)
+{
+       unsigned long start;
+       int diff;
+
+       if (__USE_RTC()) {
+               start = get_rtcl();
+               do {
+                       /* the RTCL register wraps at 1000000000 */
+                       diff = get_rtcl() - start;
+                       if (diff < 0)
+                               diff += 1000000000;
+               } while (diff < loops);
+       } else {
+               start = get_tbl();
+               while (get_tbl() - start < loops)
+                       HMT_low();
+               HMT_medium();
+       }
+}
+EXPORT_SYMBOL(__delay);
+
+void udelay(unsigned long usecs)
+{
+       __delay(tb_ticks_per_usec * usecs);
+}
+EXPORT_SYMBOL(udelay);
+
 static __inline__ void timer_check_rtc(void)
 {
         /*
@@ -261,7 +289,6 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
        do_gtod.varp = temp_varp;
        do_gtod.var_idx = temp_idx;
 
-#ifdef CONFIG_PPC64
        /*
         * tb_update_count is used to allow the userspace gettimeofday code
         * to assure itself that it sees a consistent view of the tb_to_xs and
@@ -271,14 +298,15 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
         * tb_to_xs and stamp_xsec values are consistent.  If not, then it
         * loops back and reads them again until this criteria is met.
         */
-       ++(systemcfg->tb_update_count);
+       ++(vdso_data->tb_update_count);
        smp_wmb();
-       systemcfg->tb_orig_stamp = new_tb_stamp;
-       systemcfg->stamp_xsec = new_stamp_xsec;
-       systemcfg->tb_to_xs = new_tb_to_xs;
+       vdso_data->tb_orig_stamp = new_tb_stamp;
+       vdso_data->stamp_xsec = new_stamp_xsec;
+       vdso_data->tb_to_xs = new_tb_to_xs;
+       vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
+       vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
        smp_wmb();
-       ++(systemcfg->tb_update_count);
-#endif
+       ++(vdso_data->tb_update_count);
 }
 
 /*
@@ -357,8 +385,8 @@ static void iSeries_tb_recal(void)
                                do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
                                tb_to_xs = divres.result_low;
                                do_gtod.varp->tb_to_xs = tb_to_xs;
-                               systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
-                               systemcfg->tb_to_xs = tb_to_xs;
+                               vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
+                               vdso_data->tb_to_xs = tb_to_xs;
                        }
                        else {
                                printk( "Titan recalibrate: FAILED (difference > 4 percent)\n"
@@ -403,7 +431,7 @@ void timer_interrupt(struct pt_regs * regs)
        profile_tick(CPU_PROFILING, regs);
 
 #ifdef CONFIG_PPC_ISERIES
-       get_paca()->lppaca.int_dword.fields.decr_int = 0;
+       get_lppaca()->int_dword.fields.decr_int = 0;
 #endif
 
        while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
@@ -483,6 +511,8 @@ void __init smp_space_timers(unsigned int max_cpus)
        unsigned long offset = tb_ticks_per_jiffy / max_cpus;
        unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
 
+       /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
+       previous_tb -= tb_ticks_per_jiffy;
        for_each_cpu(i) {
                if (i != boot_cpuid) {
                        previous_tb += offset;
@@ -558,10 +588,8 @@ int do_settimeofday(struct timespec *tv)
        new_xsec += (u64)new_sec * XSEC_PER_SEC - tb_delta_xs;
        update_gtod(tb_last_jiffy, new_xsec, do_gtod.varp->tb_to_xs);
 
-#ifdef CONFIG_PPC64
-       systemcfg->tz_minuteswest = sys_tz.tz_minuteswest;
-       systemcfg->tz_dsttime = sys_tz.tz_dsttime;
-#endif
+       vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
+       vdso_data->tz_dsttime = sys_tz.tz_dsttime;
 
        write_sequnlock_irqrestore(&xtime_lock, flags);
        clock_was_set();
@@ -671,10 +699,6 @@ void __init time_init(void)
        div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res);
        tb_to_xs = res.result_low;
 
-#ifdef CONFIG_PPC64
-       get_paca()->default_decr = tb_ticks_per_jiffy;
-#endif
-
        /*
         * Compute scale factor for sched_clock.
         * The calibrate_decr() function has set tb_ticks_per_sec,
@@ -710,13 +734,12 @@ void __init time_init(void)
        do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
        do_gtod.varp->tb_to_xs = tb_to_xs;
        do_gtod.tb_to_us = tb_to_us;
-#ifdef CONFIG_PPC64
-       systemcfg->tb_orig_stamp = tb_last_jiffy;
-       systemcfg->tb_update_count = 0;
-       systemcfg->tb_ticks_per_sec = tb_ticks_per_sec;
-       systemcfg->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
-       systemcfg->tb_to_xs = tb_to_xs;
-#endif
+
+       vdso_data->tb_orig_stamp = tb_last_jiffy;
+       vdso_data->tb_update_count = 0;
+       vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
+       vdso_data->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
+       vdso_data->tb_to_xs = tb_to_xs;
 
        time_freq = 0;