From: john stultz Change the current_tick_length() function so it takes an argument which specifies how much precision to return in shifted nanoseconds. This provides a simple way to convert between NTPs internal nanoseconds shifted by (SHIFT_SCALE - 10) to other shifted nanosecond units that are used by the clocksource abstraction. Signed-off-by: John Stultz Signed-off-by: Andrew Morton --- arch/powerpc/kernel/time.c | 2 +- include/linux/timex.h | 2 +- kernel/timer.c | 21 +++++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff -puN arch/powerpc/kernel/time.c~time-let-user-request-precision-from-current_tick_length arch/powerpc/kernel/time.c --- devel/arch/powerpc/kernel/time.c~time-let-user-request-precision-from-current_tick_length 2006-04-05 21:28:19.000000000 -0700 +++ devel-akpm/arch/powerpc/kernel/time.c 2006-04-05 21:28:19.000000000 -0700 @@ -535,7 +535,7 @@ static __inline__ void timer_recalc_offs if (__USE_RTC()) return; - tlen = current_tick_length(); + tlen = current_tick_length(SHIFT_SCALE - 10); offset = cur_tb - do_gtod.varp->tb_orig_stamp; if (tlen == last_tick_len && offset < 0x80000000u) return; diff -puN include/linux/timex.h~time-let-user-request-precision-from-current_tick_length include/linux/timex.h --- devel/include/linux/timex.h~time-let-user-request-precision-from-current_tick_length 2006-04-05 21:28:19.000000000 -0700 +++ devel-akpm/include/linux/timex.h 2006-04-05 21:28:19.000000000 -0700 @@ -305,7 +305,7 @@ time_interpolator_reset(void) #endif /* !CONFIG_TIME_INTERPOLATION */ /* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */ -extern u64 current_tick_length(void); +extern u64 current_tick_length(long); extern int do_adjtimex(struct timex *); diff -puN kernel/timer.c~time-let-user-request-precision-from-current_tick_length kernel/timer.c --- devel/kernel/timer.c~time-let-user-request-precision-from-current_tick_length 2006-04-05 21:28:19.000000000 -0700 +++ devel-akpm/kernel/timer.c 2006-04-05 21:28:19.000000000 -0700 @@ -768,16 +768,29 @@ static void update_wall_time_one_tick(vo * Return how long ticks are at the moment, that is, how much time * update_wall_time_one_tick will add to xtime next time we call it * (assuming no calls to do_adjtimex in the meantime). - * The return value is in fixed-point nanoseconds with SHIFT_SCALE-10 - * bits to the right of the binary point. + * The return value is in fixed-point nanoseconds shifted by the + * specified number of bits to the right of the binary point. * This function has no side-effects. */ -u64 current_tick_length(void) +u64 current_tick_length(long shift) { long delta_nsec; + u64 ret; + /* calculate the finest interval NTP will allow. + * ie: nanosecond value shifted by (SHIFT_SCALE - 10) + */ delta_nsec = tick_nsec + adjtime_adjustment() * 1000; - return ((u64) delta_nsec << (SHIFT_SCALE - 10)) + time_adj; + ret = ((u64) delta_nsec << (SHIFT_SCALE - 10)) + time_adj; + + /* convert from (SHIFT_SCALE - 10) to specified shift scale: */ + shift = shift - (SHIFT_SCALE - 10); + if (shift < 0) + ret >>= -shift; + else + ret <<= shift; + + return ret; } /* XXX - all of this timekeeping code should be later moved to time.c */ _