Merge branch 'powerpc.cherry-picks' into timers/clocksource
authorThomas Gleixner <tglx@linutronix.de>
Wed, 28 Jul 2010 19:49:22 +0000 (21:49 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Wed, 28 Jul 2010 19:49:22 +0000 (21:49 +0200)
Conflicts:
arch/powerpc/kernel/time.c

Reason: The powerpc next tree contains two commits which conflict with
the timekeeping changes:

8fd63a9e powerpc: Rework VDSO gettimeofday to prevent time going backwards
c1aa687d powerpc: Clean up obsolete code relating to decrementer and timebase

John Stultz identified them and provided the conflict resolution.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1  2 
arch/powerpc/kernel/time.c

@@@ -849,25 -796,10 +796,30 @@@ static cycle_t timebase_read(struct clo
        return (cycle_t)get_tb();
  }
  
 -static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
 -                             u64 new_tb_to_xs, struct timespec *now,
 -                             u32 frac_sec)
 +void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
 +                      struct clocksource *clock, u32 mult)
  {
 +      u64 new_tb_to_xs, new_stamp_xsec;
++      u32 frac_sec;
 +
 +      if (clock != &clocksource_timebase)
 +              return;
 +
 +      /* Make userspace gettimeofday spin until we're done. */
 +      ++vdso_data->tb_update_count;
 +      smp_mb();
 +
 +      /* XXX this assumes clock->shift == 22 */
 +      /* 4611686018 ~= 2^(20+64-22) / 1e9 */
 +      new_tb_to_xs = (u64) mult * 4611686018ULL;
 +      new_stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
 +      do_div(new_stamp_xsec, 1000000000);
 +      new_stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC;
 +
++      BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC);
++      /* this is tv_nsec / 1e9 as a 0.32 fraction */
++      frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32;
++
        /*
         * 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
         * We expect the caller to have done the first increment of
         * vdso_data->tb_update_count already.
         */
 -      vdso_data->tb_orig_stamp = new_tb_stamp;
 +      vdso_data->tb_orig_stamp = clock->cycle_last;
        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;
 -      vdso_data->stamp_xtime = *now;
 +      vdso_data->wtom_clock_sec = wtm->tv_sec;
 +      vdso_data->wtom_clock_nsec = wtm->tv_nsec;
 +      vdso_data->stamp_xtime = *wall_time;
+       vdso_data->stamp_sec_fraction = frac_sec;
        smp_wmb();
        ++(vdso_data->tb_update_count);
  }