]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kernel/time.c
Merge Paulus' tree
[karo-tx-linux.git] / arch / powerpc / kernel / time.c
index ad501d62aa6edded0b415d559df0977a324108d1..6996a593dcb39b91422fa205f2af8057c2109165 100644 (file)
 #include <asm/firmware.h>
 #endif
 #ifdef CONFIG_PPC_ISERIES
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/HvCallXm.h>
+#include <asm/iseries/it_lp_queue.h>
+#include <asm/iseries/hv_call_xm.h>
 #endif
 
-u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
-
-EXPORT_SYMBOL(jiffies_64);
-
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
 extern int piranha_simulator;
@@ -154,7 +150,7 @@ static __inline__ void timer_check_rtc(void)
          * We should have an rtc call that only sets the minutes and
          * seconds like on Intel to avoid problems with non UTC clocks.
          */
-        if (ntp_synced() &&
+        if (ppc_md.set_rtc_time && ntp_synced() &&
            xtime.tv_sec - last_rtc_update >= 659 &&
            abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ &&
            jiffies - wall_jiffies == 1) {
@@ -518,7 +514,7 @@ int do_settimeofday(struct timespec *tv)
        long wtm_nsec, new_nsec = tv->tv_nsec;
        unsigned long flags;
        long int tb_delta;
-       u64 new_xsec;
+       u64 new_xsec, tb_delta_xs;
 
        if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
                return -EINVAL;
@@ -541,8 +537,7 @@ int do_settimeofday(struct timespec *tv)
 #endif
        tb_delta = tb_ticks_since(tb_last_stamp);
        tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
-
-       new_nsec -= 1000 * mulhwu(tb_to_us, tb_delta);
+       tb_delta_xs = mulhdu(tb_delta, do_gtod.varp->tb_to_xs);
 
        wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - new_sec);
        wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - new_nsec);
@@ -557,9 +552,12 @@ int do_settimeofday(struct timespec *tv)
 
        ntp_clear();
 
-       new_xsec = (u64)new_nsec * XSEC_PER_SEC;
-       do_div(new_xsec, NSEC_PER_SEC);
-       new_xsec += (u64)new_sec * XSEC_PER_SEC;
+       new_xsec = 0;
+       if (new_nsec != 0) {
+               new_xsec = (u64)new_nsec * XSEC_PER_SEC;
+               do_div(new_xsec, NSEC_PER_SEC);
+       }
+       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
@@ -610,6 +608,17 @@ void __init generic_calibrate_decr(void)
                        ppc_proc_freq = *fp;
                }
        }
+#ifdef CONFIG_BOOKE
+       /* Set the time base to zero */
+       mtspr(SPRN_TBWL, 0);
+       mtspr(SPRN_TBWU, 0);
+
+       /* Clear any pending timer interrupts */
+       mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+       /* Enable decrementer interrupt */
+       mtspr(SPRN_TCR, TCR_DIE);
+#endif
        if (!node_found)
                printk(KERN_ERR "WARNING: Estimating processor frequency "
                                "(not found)\n");