Browse Source

Merge branch 'timers-timekeeping-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-timekeeping-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  um: Fix read_persistent_clock fallout
  kgdb: Do not access xtime directly
  powerpc: Clean up obsolete code relating to decrementer and timebase
  powerpc: Rework VDSO gettimeofday to prevent time going backwards
  clocksource: Add __clocksource_updatefreq_hz/khz methods
  x86: Convert common clocksources to use clocksource_register_hz/khz
  timekeeping: Make xtime and wall_to_monotonic static
  hrtimer: Cleanup direct access to wall_to_monotonic
  um: Convert to use read_persistent_clock
  timkeeping: Fix update_vsyscall to provide wall_to_monotonic offset
  powerpc: Cleanup xtime usage
  powerpc: Simplify update_vsyscall
  time: Kill off CONFIG_GENERIC_TIME
  time: Implement timespec_add
  x86: Fix vtime/file timestamp inconsistencies

Trivial conflicts in Documentation/feature-removal-schedule.txt

Much less trivial conflicts in arch/powerpc/kernel/time.c resolved as
per Thomas' earlier merge commit 47916be4e28c ("Merge branch
'powerpc.cherry-picks' into timers/clocksource")
Linus Torvalds 15 years ago
parent
commit
b62ad9ab18

+ 0 - 10
Documentation/feature-removal-schedule.txt

@@ -445,16 +445,6 @@ Who:	Jan Kiszka <jan.kiszka@web.de>
 
 
 ----------------------------
 ----------------------------
 
 
-What:	xtime, wall_to_monotonic
-When:	2.6.36+
-Files:	kernel/time/timekeeping.c include/linux/time.h
-Why:	Cleaning up timekeeping internal values. Please use
-	existing timekeeping accessor functions to access
-	the equivalent functionality.
-Who:	John Stultz <johnstul@us.ibm.com>
-
-----------------------------
-
 What:	KVM paravirt mmu host support
 What:	KVM paravirt mmu host support
 When:	January 2011
 When:	January 2011
 Why:	The paravirt mmu host support is slower than non-paravirt mmu, both
 Why:	The paravirt mmu host support is slower than non-paravirt mmu, both

+ 1 - 2
Documentation/kernel-parameters.txt

@@ -73,7 +73,6 @@ parameter is applicable:
 	MTD	MTD (Memory Technology Device) support is enabled.
 	MTD	MTD (Memory Technology Device) support is enabled.
 	NET	Appropriate network support is enabled.
 	NET	Appropriate network support is enabled.
 	NUMA	NUMA support is enabled.
 	NUMA	NUMA support is enabled.
-	GENERIC_TIME The generic timeofday code is enabled.
 	NFS	Appropriate NFS support is enabled.
 	NFS	Appropriate NFS support is enabled.
 	OSS	OSS sound support is enabled.
 	OSS	OSS sound support is enabled.
 	PV_OPS	A paravirtualized kernel is enabled.
 	PV_OPS	A paravirtualized kernel is enabled.
@@ -470,7 +469,7 @@ and is between 256 and 4096 characters. It is defined in the file
 			clocksource is not available, it defaults to PIT.
 			clocksource is not available, it defaults to PIT.
 			Format: { pit | tsc | cyclone | pmtmr }
 			Format: { pit | tsc | cyclone | pmtmr }
 
 
-	clocksource=	[GENERIC_TIME] Override the default clocksource
+	clocksource=	Override the default clocksource
 			Format: <string>
 			Format: <string>
 			Override the default clocksource and use the clocksource
 			Override the default clocksource and use the clocksource
 			with the name specified.
 			with the name specified.

+ 0 - 4
arch/alpha/Kconfig

@@ -47,10 +47,6 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	bool
 	default y
 	default y
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config GENERIC_CMOS_UPDATE
 config GENERIC_CMOS_UPDATE
         def_bool y
         def_bool y
 
 

+ 0 - 4
arch/arm/Kconfig

@@ -43,10 +43,6 @@ config SYS_SUPPORTS_APM_EMULATION
 config GENERIC_GPIO
 config GENERIC_GPIO
 	bool
 	bool
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config ARCH_USES_GETTIMEOFFSET
 config ARCH_USES_GETTIMEOFFSET
 	bool
 	bool
 	default n
 	default n

+ 0 - 3
arch/avr32/Kconfig

@@ -45,9 +45,6 @@ config GENERIC_IRQ_PROBE
 config RWSEM_GENERIC_SPINLOCK
 config RWSEM_GENERIC_SPINLOCK
 	def_bool y
 	def_bool y
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_CLOCKEVENTS
 config GENERIC_CLOCKEVENTS
 	def_bool y
 	def_bool y
 
 

+ 0 - 3
arch/blackfin/Kconfig

@@ -614,9 +614,6 @@ comment "Kernel Timer/Scheduler"
 
 
 source kernel/Kconfig.hz
 source kernel/Kconfig.hz
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_CLOCKEVENTS
 config GENERIC_CLOCKEVENTS
 	bool "Generic clock events"
 	bool "Generic clock events"
 	default y
 	default y

+ 0 - 3
arch/cris/Kconfig

@@ -20,9 +20,6 @@ config RWSEM_GENERIC_SPINLOCK
 config RWSEM_XCHGADD_ALGORITHM
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 	bool
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_CMOS_UPDATE
 config GENERIC_CMOS_UPDATE
 	def_bool y
 	def_bool y
 
 

+ 0 - 4
arch/frv/Kconfig

@@ -40,10 +40,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
 	bool
 	bool
 	default y
 	default y
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config TIME_LOW_RES
 config TIME_LOW_RES
 	bool
 	bool
 	default y
 	default y

+ 0 - 4
arch/h8300/Kconfig

@@ -62,10 +62,6 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	bool
 	default y
 	default y
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config GENERIC_BUG
 config GENERIC_BUG
         bool
         bool
         depends on BUG
         depends on BUG

+ 0 - 4
arch/ia64/Kconfig

@@ -82,10 +82,6 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	bool
 	default y
 	default y
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config GENERIC_TIME_VSYSCALL
 config GENERIC_TIME_VSYSCALL
 	bool
 	bool
 	default y
 	default y

+ 4 - 3
arch/ia64/kernel/time.c

@@ -471,7 +471,8 @@ void update_vsyscall_tz(void)
 {
 {
 }
 }
 
 
-void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
+void update_vsyscall(struct timespec *wall, struct timespec *wtm,
+			struct clocksource *c, u32 mult)
 {
 {
         unsigned long flags;
         unsigned long flags;
 
 
@@ -487,9 +488,9 @@ void update_vsyscall(struct timespec *wall, struct clocksource *c, u32 mult)
 	/* copy kernel time structures */
 	/* copy kernel time structures */
         fsyscall_gtod_data.wall_time.tv_sec = wall->tv_sec;
         fsyscall_gtod_data.wall_time.tv_sec = wall->tv_sec;
         fsyscall_gtod_data.wall_time.tv_nsec = wall->tv_nsec;
         fsyscall_gtod_data.wall_time.tv_nsec = wall->tv_nsec;
-        fsyscall_gtod_data.monotonic_time.tv_sec = wall_to_monotonic.tv_sec
+	fsyscall_gtod_data.monotonic_time.tv_sec = wtm->tv_sec
 							+ wall->tv_sec;
 							+ wall->tv_sec;
-        fsyscall_gtod_data.monotonic_time.tv_nsec = wall_to_monotonic.tv_nsec
+	fsyscall_gtod_data.monotonic_time.tv_nsec = wtm->tv_nsec
 							+ wall->tv_nsec;
 							+ wall->tv_nsec;
 
 
 	/* normalize */
 	/* normalize */

+ 0 - 3
arch/m32r/Kconfig

@@ -44,9 +44,6 @@ config HZ
 	int
 	int
 	default 100
 	default 100
 
 
-config GENERIC_TIME
-	def_bool y
-
 config ARCH_USES_GETTIMEOFFSET
 config ARCH_USES_GETTIMEOFFSET
 	def_bool y
 	def_bool y
 
 

+ 0 - 3
arch/m68k/Kconfig

@@ -59,9 +59,6 @@ config HZ
 	int
 	int
 	default 100
 	default 100
 
 
-config GENERIC_TIME
-	def_bool y
-
 config ARCH_USES_GETTIMEOFFSET
 config ARCH_USES_GETTIMEOFFSET
 	def_bool y
 	def_bool y
 
 

+ 0 - 4
arch/m68knommu/Kconfig

@@ -63,10 +63,6 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	bool
 	default y
 	default y
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config GENERIC_CMOS_UPDATE
 config GENERIC_CMOS_UPDATE
 	bool
 	bool
 	default y
 	default y

+ 0 - 3
arch/microblaze/Kconfig

@@ -51,9 +51,6 @@ config GENERIC_IRQ_PROBE
 config GENERIC_CALIBRATE_DELAY
 config GENERIC_CALIBRATE_DELAY
 	def_bool y
 	def_bool y
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_TIME_VSYSCALL
 config GENERIC_TIME_VSYSCALL
 	def_bool n
 	def_bool n
 
 

+ 0 - 4
arch/mips/Kconfig

@@ -758,10 +758,6 @@ config GENERIC_CLOCKEVENTS
 	bool
 	bool
 	default y
 	default y
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config GENERIC_CMOS_UPDATE
 config GENERIC_CMOS_UPDATE
 	bool
 	bool
 	default y
 	default y

+ 0 - 3
arch/mn10300/Kconfig

@@ -46,9 +46,6 @@ config GENERIC_FIND_NEXT_BIT
 config GENERIC_HWEIGHT
 config GENERIC_HWEIGHT
 	def_bool y
 	def_bool y
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_BUG
 config GENERIC_BUG
 	def_bool y
 	def_bool y
 
 

+ 0 - 4
arch/parisc/Kconfig

@@ -66,10 +66,6 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	bool
 	default y
 	default y
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config TIME_LOW_RES
 config TIME_LOW_RES
 	bool
 	bool
 	depends on SMP
 	depends on SMP

+ 0 - 3
arch/powerpc/Kconfig

@@ -29,9 +29,6 @@ config MMU
 config GENERIC_CMOS_UPDATE
 config GENERIC_CMOS_UPDATE
 	def_bool y
 	def_bool y
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_TIME_VSYSCALL
 config GENERIC_TIME_VSYSCALL
 	def_bool y
 	def_bool y
 
 

+ 27 - 33
arch/powerpc/kernel/time.c

@@ -796,10 +796,30 @@ static cycle_t timebase_read(struct clocksource *cs)
 	return (cycle_t)get_tb();
 	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
 	 * 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
 	 * to assure itself that it sees a consistent view of the tb_to_xs and
@@ -811,43 +831,17 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
 	 * We expect the caller to have done the first increment of
 	 * We expect the caller to have done the first increment of
 	 * vdso_data->tb_update_count already.
 	 * 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->stamp_xsec = new_stamp_xsec;
 	vdso_data->tb_to_xs = new_tb_to_xs;
 	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;
 	vdso_data->stamp_sec_fraction = frac_sec;
 	smp_wmb();
 	smp_wmb();
 	++(vdso_data->tb_update_count);
 	++(vdso_data->tb_update_count);
 }
 }
 
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
-		     u32 mult)
-{
-	u64 t2x, 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 */
-	t2x = (u64) mult * 4611686018ULL;
-	stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
-	do_div(stamp_xsec, 1000000000);
-	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;
-	update_gtod(clock->cycle_last, stamp_xsec, t2x, wall_time, frac_sec);
-}
-
 void update_vsyscall_tz(void)
 void update_vsyscall_tz(void)
 {
 {
 	/* Make userspace gettimeofday spin until we're done. */
 	/* Make userspace gettimeofday spin until we're done. */

+ 0 - 3
arch/s390/Kconfig

@@ -40,9 +40,6 @@ config ARCH_HAS_ILOG2_U64
 config GENERIC_HWEIGHT
 config GENERIC_HWEIGHT
 	def_bool y
 	def_bool y
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_TIME_VSYSCALL
 config GENERIC_TIME_VSYSCALL
 	def_bool y
 	def_bool y
 
 

+ 4 - 4
arch/s390/kernel/time.c

@@ -207,8 +207,8 @@ struct clocksource * __init clocksource_default_clock(void)
 	return &clocksource_tod;
 	return &clocksource_tod;
 }
 }
 
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
-		     u32 mult)
+void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
+			struct clocksource *clock, u32 mult)
 {
 {
 	if (clock != &clocksource_tod)
 	if (clock != &clocksource_tod)
 		return;
 		return;
@@ -219,8 +219,8 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
 	vdso_data->xtime_tod_stamp = clock->cycle_last;
 	vdso_data->xtime_tod_stamp = clock->cycle_last;
 	vdso_data->xtime_clock_sec = wall_time->tv_sec;
 	vdso_data->xtime_clock_sec = wall_time->tv_sec;
 	vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
 	vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
-	vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
-	vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+	vdso_data->wtom_clock_sec = wtm->tv_sec;
+	vdso_data->wtom_clock_nsec = wtm->tv_nsec;
 	vdso_data->ntp_mult = mult;
 	vdso_data->ntp_mult = mult;
 	smp_wmb();
 	smp_wmb();
 	++vdso_data->tb_update_count;
 	++vdso_data->tb_update_count;

+ 0 - 3
arch/score/Kconfig

@@ -55,9 +55,6 @@ config GENERIC_CALIBRATE_DELAY
 config GENERIC_CLOCKEVENTS
 config GENERIC_CLOCKEVENTS
 	def_bool y
 	def_bool y
 
 
-config GENERIC_TIME
-	def_bool y
-
 config SCHED_NO_NO_OMIT_FRAME_POINTER
 config SCHED_NO_NO_OMIT_FRAME_POINTER
 	def_bool y
 	def_bool y
 
 

+ 0 - 3
arch/sh/Kconfig

@@ -98,9 +98,6 @@ config GENERIC_CALIBRATE_DELAY
 config GENERIC_IOMAP
 config GENERIC_IOMAP
 	bool
 	bool
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_CLOCKEVENTS
 config GENERIC_CLOCKEVENTS
 	def_bool y
 	def_bool y
 
 

+ 0 - 3
arch/sparc/Kconfig

@@ -67,9 +67,6 @@ config BITS
 	default 32 if SPARC32
 	default 32 if SPARC32
 	default 64 if SPARC64
 	default 64 if SPARC64
 
 
-config GENERIC_TIME
-	def_bool y
-
 config ARCH_USES_GETTIMEOFFSET
 config ARCH_USES_GETTIMEOFFSET
 	bool
 	bool
 	default y if SPARC32
 	default y if SPARC32

+ 0 - 4
arch/um/Kconfig.common

@@ -55,10 +55,6 @@ config GENERIC_BUG
 	default y
 	default y
 	depends on BUG
 	depends on BUG
 
 
-config GENERIC_TIME
-	bool
-	default y
-
 config GENERIC_CLOCKEVENTS
 config GENERIC_CLOCKEVENTS
 	bool
 	bool
 	default y
 	default y

+ 8 - 8
arch/um/kernel/time.c

@@ -102,16 +102,16 @@ static void __init setup_itimer(void)
 	clockevents_register_device(&itimer_clockevent);
 	clockevents_register_device(&itimer_clockevent);
 }
 }
 
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
 {
-	long long nsecs;
-
-	timer_init();
+	long long nsecs = os_nsecs();
 
 
-	nsecs = os_nsecs();
-	set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC,
-				-nsecs % NSEC_PER_SEC);
-	set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC,
+	set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
 				nsecs % NSEC_PER_SEC);
 				nsecs % NSEC_PER_SEC);
+}
+
+void __init time_init(void)
+{
+	timer_init();
 	late_time_init = setup_itimer;
 	late_time_init = setup_itimer;
 }
 }

+ 1 - 4
arch/x86/Kconfig

@@ -73,9 +73,6 @@ config ARCH_DEFCONFIG
 	default "arch/x86/configs/i386_defconfig" if X86_32
 	default "arch/x86/configs/i386_defconfig" if X86_32
 	default "arch/x86/configs/x86_64_defconfig" if X86_64
 	default "arch/x86/configs/x86_64_defconfig" if X86_64
 
 
-config GENERIC_TIME
-	def_bool y
-
 config GENERIC_CMOS_UPDATE
 config GENERIC_CMOS_UPDATE
 	def_bool y
 	def_bool y
 
 
@@ -2047,7 +2044,7 @@ config SCx200
 
 
 config SCx200HR_TIMER
 config SCx200HR_TIMER
 	tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
 	tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
-	depends on SCx200 && GENERIC_TIME
+	depends on SCx200
 	default y
 	default y
 	---help---
 	---help---
 	  This driver provides a clocksource built upon the on-chip
 	  This driver provides a clocksource built upon the on-chip

+ 9 - 4
arch/x86/kernel/hpet.c

@@ -16,7 +16,6 @@
 #include <asm/hpet.h>
 #include <asm/hpet.h>
 
 
 #define HPET_MASK			CLOCKSOURCE_MASK(32)
 #define HPET_MASK			CLOCKSOURCE_MASK(32)
-#define HPET_SHIFT			22
 
 
 /* FSEC = 10^-15
 /* FSEC = 10^-15
    NSEC = 10^-9 */
    NSEC = 10^-9 */
@@ -787,7 +786,6 @@ static struct clocksource clocksource_hpet = {
 	.rating		= 250,
 	.rating		= 250,
 	.read		= read_hpet,
 	.read		= read_hpet,
 	.mask		= HPET_MASK,
 	.mask		= HPET_MASK,
-	.shift		= HPET_SHIFT,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 	.resume		= hpet_resume_counter,
 	.resume		= hpet_resume_counter,
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_X86_64
@@ -798,6 +796,7 @@ static struct clocksource clocksource_hpet = {
 static int hpet_clocksource_register(void)
 static int hpet_clocksource_register(void)
 {
 {
 	u64 start, now;
 	u64 start, now;
+	u64 hpet_freq;
 	cycle_t t1;
 	cycle_t t1;
 
 
 	/* Start the counter */
 	/* Start the counter */
@@ -832,9 +831,15 @@ static int hpet_clocksource_register(void)
 	 *  mult = (hpet_period * 2^shift)/10^6
 	 *  mult = (hpet_period * 2^shift)/10^6
 	 *  mult = (hpet_period << shift)/FSEC_PER_NSEC
 	 *  mult = (hpet_period << shift)/FSEC_PER_NSEC
 	 */
 	 */
-	clocksource_hpet.mult = div_sc(hpet_period, FSEC_PER_NSEC, HPET_SHIFT);
 
 
-	clocksource_register(&clocksource_hpet);
+	/* Need to convert hpet_period (fsec/cyc) to cyc/sec:
+	 *
+	 * cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc)
+	 * cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period
+	 */
+	hpet_freq = FSEC_PER_NSEC * NSEC_PER_SEC;
+	do_div(hpet_freq, hpet_period);
+	clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 4
arch/x86/kernel/tsc.c

@@ -751,7 +751,6 @@ static struct clocksource clocksource_tsc = {
 	.read                   = read_tsc,
 	.read                   = read_tsc,
 	.resume			= resume_tsc,
 	.resume			= resume_tsc,
 	.mask                   = CLOCKSOURCE_MASK(64),
 	.mask                   = CLOCKSOURCE_MASK(64),
-	.shift                  = 22,
 	.flags                  = CLOCK_SOURCE_IS_CONTINUOUS |
 	.flags                  = CLOCK_SOURCE_IS_CONTINUOUS |
 				  CLOCK_SOURCE_MUST_VERIFY,
 				  CLOCK_SOURCE_MUST_VERIFY,
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_X86_64
@@ -845,8 +844,6 @@ __cpuinit int unsynchronized_tsc(void)
 
 
 static void __init init_tsc_clocksource(void)
 static void __init init_tsc_clocksource(void)
 {
 {
-	clocksource_tsc.mult = clocksource_khz2mult(tsc_khz,
-			clocksource_tsc.shift);
 	if (tsc_clocksource_reliable)
 	if (tsc_clocksource_reliable)
 		clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
 		clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
 	/* lower the rating if we already know its unstable: */
 	/* lower the rating if we already know its unstable: */
@@ -854,7 +851,7 @@ static void __init init_tsc_clocksource(void)
 		clocksource_tsc.rating = 0;
 		clocksource_tsc.rating = 0;
 		clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
 		clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
 	}
 	}
-	clocksource_register(&clocksource_tsc);
+	clocksource_register_khz(&clocksource_tsc, tsc_khz);
 }
 }
 
 
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_X86_64

+ 11 - 6
arch/x86/kernel/vsyscall_64.c

@@ -73,8 +73,8 @@ void update_vsyscall_tz(void)
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 }
 
 
-void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
-		     u32 mult)
+void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
+			struct clocksource *clock, u32 mult)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -87,7 +87,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
 	vsyscall_gtod_data.clock.shift = clock->shift;
 	vsyscall_gtod_data.clock.shift = clock->shift;
 	vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
 	vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
 	vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
 	vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
-	vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
+	vsyscall_gtod_data.wall_to_monotonic = *wtm;
 	vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
 	vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 }
@@ -169,13 +169,18 @@ int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
  * unlikely */
  * unlikely */
 time_t __vsyscall(1) vtime(time_t *t)
 time_t __vsyscall(1) vtime(time_t *t)
 {
 {
-	struct timeval tv;
+	unsigned seq;
 	time_t result;
 	time_t result;
 	if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
 	if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
 		return time_syscall(t);
 		return time_syscall(t);
 
 
-	vgettimeofday(&tv, NULL);
-	result = tv.tv_sec;
+	do {
+		seq = read_seqbegin(&__vsyscall_gtod_data.lock);
+
+		result = __vsyscall_gtod_data.wall_time_sec;
+
+	} while (read_seqretry(&__vsyscall_gtod_data.lock, seq));
+
 	if (t)
 	if (t)
 		*t = result;
 		*t = result;
 	return result;
 	return result;

+ 0 - 3
arch/xtensa/Kconfig

@@ -48,9 +48,6 @@ config HZ
 	int
 	int
 	default 100
 	default 100
 
 
-config GENERIC_TIME
-	def_bool y
-
 source "init/Kconfig"
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 source "kernel/Kconfig.freezer"
 
 

+ 3 - 1
drivers/Makefile

@@ -101,7 +101,9 @@ obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
 obj-$(CONFIG_CRYPTO)		+= crypto/
 obj-$(CONFIG_SUPERH)		+= sh/
 obj-$(CONFIG_SUPERH)		+= sh/
 obj-$(CONFIG_ARCH_SHMOBILE)	+= sh/
 obj-$(CONFIG_ARCH_SHMOBILE)	+= sh/
-obj-$(CONFIG_GENERIC_TIME)	+= clocksource/
+ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
+obj-y				+= clocksource/
+endif
 obj-$(CONFIG_DMA_ENGINE)	+= dma/
 obj-$(CONFIG_DMA_ENGINE)	+= dma/
 obj-$(CONFIG_DCA)		+= dca/
 obj-$(CONFIG_DCA)		+= dca/
 obj-$(CONFIG_HID)		+= hid/
 obj-$(CONFIG_HID)		+= hid/

+ 1 - 1
drivers/acpi/acpi_pad.c

@@ -77,7 +77,7 @@ static void power_saving_mwait_init(void)
 	power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
 	power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
 		(highest_subcstate - 1);
 		(highest_subcstate - 1);
 
 
-#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86)
+#if defined(CONFIG_X86)
 	switch (boot_cpu_data.x86_vendor) {
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
 	case X86_VENDOR_AMD:
 	case X86_VENDOR_INTEL:
 	case X86_VENDOR_INTEL:

+ 1 - 1
drivers/acpi/processor_idle.c

@@ -264,7 +264,7 @@ int acpi_processor_resume(struct acpi_device * device)
 	return 0;
 	return 0;
 }
 }
 
 
-#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
+#if defined(CONFIG_X86)
 static void tsc_check_state(int state)
 static void tsc_check_state(int state)
 {
 {
 	switch (boot_cpu_data.x86_vendor) {
 	switch (boot_cpu_data.x86_vendor) {

+ 2 - 7
drivers/clocksource/acpi_pm.c

@@ -68,10 +68,7 @@ static struct clocksource clocksource_acpi_pm = {
 	.rating		= 200,
 	.rating		= 200,
 	.read		= acpi_pm_read,
 	.read		= acpi_pm_read,
 	.mask		= (cycle_t)ACPI_PM_MASK,
 	.mask		= (cycle_t)ACPI_PM_MASK,
-	.mult		= 0, /*to be calculated*/
-	.shift		= 22,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-
 };
 };
 
 
 
 
@@ -190,9 +187,6 @@ static int __init init_acpi_pm_clocksource(void)
 	if (!pmtmr_ioport)
 	if (!pmtmr_ioport)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	clocksource_acpi_pm.mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC,
-						clocksource_acpi_pm.shift);
-
 	/* "verify" this timing source: */
 	/* "verify" this timing source: */
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
 		udelay(100 * j);
 		udelay(100 * j);
@@ -220,7 +214,8 @@ static int __init init_acpi_pm_clocksource(void)
 	if (verify_pmtmr_rate() != 0)
 	if (verify_pmtmr_rate() != 0)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	return clocksource_register(&clocksource_acpi_pm);
+	return clocksource_register_hz(&clocksource_acpi_pm,
+						PMTMR_TICKS_PER_SEC);
 }
 }
 
 
 /* We use fs_initcall because we want the PCI fixups to have run
 /* We use fs_initcall because we want the PCI fixups to have run

+ 2 - 2
drivers/misc/Kconfig

@@ -72,7 +72,7 @@ config ATMEL_TCLIB
 
 
 config ATMEL_TCB_CLKSRC
 config ATMEL_TCB_CLKSRC
 	bool "TC Block Clocksource"
 	bool "TC Block Clocksource"
-	depends on ATMEL_TCLIB && GENERIC_TIME
+	depends on ATMEL_TCLIB
 	default y
 	default y
 	help
 	help
 	  Select this to get a high precision clocksource based on a
 	  Select this to get a high precision clocksource based on a
@@ -240,7 +240,7 @@ config CS5535_MFGPT_DEFAULT_IRQ
 
 
 config CS5535_CLOCK_EVENT_SRC
 config CS5535_CLOCK_EVENT_SRC
 	tristate "CS5535/CS5536 high-res timer (MFGPT) events"
 	tristate "CS5535/CS5536 high-res timer (MFGPT) events"
-	depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT
+	depends on GENERIC_CLOCKEVENTS && CS5535_MFGPT
 	help
 	help
 	  This driver provides a clock event source based on the MFGPT
 	  This driver provides a clock event source based on the MFGPT
 	  timer(s) in the CS5535 and CS5536 companion chips.
 	  timer(s) in the CS5535 and CS5536 companion chips.

+ 15 - 2
include/linux/clocksource.h

@@ -292,6 +292,8 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
  */
  */
 extern int
 extern int
 __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
 __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
+extern void
+__clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
 
 
 static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
 static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
 {
 {
@@ -303,6 +305,15 @@ static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
 	return __clocksource_register_scale(cs, 1000, khz);
 	return __clocksource_register_scale(cs, 1000, khz);
 }
 }
 
 
+static inline void __clocksource_updatefreq_hz(struct clocksource *cs, u32 hz)
+{
+	__clocksource_updatefreq_scale(cs, 1, hz);
+}
+
+static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz)
+{
+	__clocksource_updatefreq_scale(cs, 1000, khz);
+}
 
 
 static inline void
 static inline void
 clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
 clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
@@ -313,11 +324,13 @@ clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
 
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 extern void
 extern void
-update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult);
+update_vsyscall(struct timespec *ts, struct timespec *wtm,
+			struct clocksource *c, u32 mult);
 extern void update_vsyscall_tz(void);
 extern void update_vsyscall_tz(void);
 #else
 #else
 static inline void
 static inline void
-update_vsyscall(struct timespec *ts, struct clocksource *c, u32 mult)
+update_vsyscall(struct timespec *ts, struct timespec *wtm,
+			struct clocksource *c, u32 mult)
 {
 {
 }
 }
 
 

+ 18 - 3
include/linux/time.h

@@ -76,9 +76,25 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
 			    const unsigned int min, const unsigned int sec);
 			    const unsigned int min, const unsigned int sec);
 
 
 extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
 extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
+
+/*
+ * timespec_add_safe assumes both values are positive and checks
+ * for overflow. It will return TIME_T_MAX if the reutrn would be
+ * smaller then either of the arguments.
+ */
 extern struct timespec timespec_add_safe(const struct timespec lhs,
 extern struct timespec timespec_add_safe(const struct timespec lhs,
 					 const struct timespec rhs);
 					 const struct timespec rhs);
 
 
+
+static inline struct timespec timespec_add(struct timespec lhs,
+						struct timespec rhs)
+{
+	struct timespec ts_delta;
+	set_normalized_timespec(&ts_delta, lhs.tv_sec + rhs.tv_sec,
+				lhs.tv_nsec + rhs.tv_nsec);
+	return ts_delta;
+}
+
 /*
 /*
  * sub = lhs - rhs, in normalized form
  * sub = lhs - rhs, in normalized form
  */
  */
@@ -97,8 +113,6 @@ static inline struct timespec timespec_sub(struct timespec lhs,
 #define timespec_valid(ts) \
 #define timespec_valid(ts) \
 	(((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
 	(((ts)->tv_sec >= 0) && (((unsigned long) (ts)->tv_nsec) < NSEC_PER_SEC))
 
 
-extern struct timespec xtime;
-extern struct timespec wall_to_monotonic;
 extern seqlock_t xtime_lock;
 extern seqlock_t xtime_lock;
 
 
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_persistent_clock(struct timespec *ts);
@@ -110,7 +124,8 @@ extern int timekeeping_suspended;
 
 
 unsigned long get_seconds(void);
 unsigned long get_seconds(void);
 struct timespec current_kernel_time(void);
 struct timespec current_kernel_time(void);
-struct timespec __current_kernel_time(void); /* does not hold xtime_lock */
+struct timespec __current_kernel_time(void); /* does not take xtime_lock */
+struct timespec __get_wall_to_monotonic(void); /* does not take xtime_lock */
 struct timespec get_monotonic_coarse(void);
 struct timespec get_monotonic_coarse(void);
 
 
 #define CURRENT_TIME		(current_kernel_time())
 #define CURRENT_TIME		(current_kernel_time())

+ 3 - 1
kernel/debug/kdb/kdb_main.c

@@ -2548,6 +2548,7 @@ static void kdb_sysinfo(struct sysinfo *val)
  */
  */
 static int kdb_summary(int argc, const char **argv)
 static int kdb_summary(int argc, const char **argv)
 {
 {
+	struct timespec now;
 	struct kdb_tm tm;
 	struct kdb_tm tm;
 	struct sysinfo val;
 	struct sysinfo val;
 
 
@@ -2562,7 +2563,8 @@ static int kdb_summary(int argc, const char **argv)
 	kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
 	kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
 	kdb_printf("ccversion  %s\n", __stringify(CCVERSION));
 	kdb_printf("ccversion  %s\n", __stringify(CCVERSION));
 
 
-	kdb_gmtime(&xtime, &tm);
+	now = __current_kernel_time();
+	kdb_gmtime(&now, &tm);
 	kdb_printf("date       %04d-%02d-%02d %02d:%02d:%02d "
 	kdb_printf("date       %04d-%02d-%02d %02d:%02d:%02d "
 		   "tz_minuteswest %d\n",
 		   "tz_minuteswest %d\n",
 		1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
 		1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,

+ 4 - 5
kernel/hrtimer.c

@@ -90,7 +90,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
 	do {
 	do {
 		seq = read_seqbegin(&xtime_lock);
 		seq = read_seqbegin(&xtime_lock);
 		xts = __current_kernel_time();
 		xts = __current_kernel_time();
-		tom = wall_to_monotonic;
+		tom = __get_wall_to_monotonic();
 	} while (read_seqretry(&xtime_lock, seq));
 	} while (read_seqretry(&xtime_lock, seq));
 
 
 	xtim = timespec_to_ktime(xts);
 	xtim = timespec_to_ktime(xts);
@@ -608,7 +608,7 @@ static int hrtimer_reprogram(struct hrtimer *timer,
 static void retrigger_next_event(void *arg)
 static void retrigger_next_event(void *arg)
 {
 {
 	struct hrtimer_cpu_base *base;
 	struct hrtimer_cpu_base *base;
-	struct timespec realtime_offset;
+	struct timespec realtime_offset, wtm;
 	unsigned long seq;
 	unsigned long seq;
 
 
 	if (!hrtimer_hres_active())
 	if (!hrtimer_hres_active())
@@ -616,10 +616,9 @@ static void retrigger_next_event(void *arg)
 
 
 	do {
 	do {
 		seq = read_seqbegin(&xtime_lock);
 		seq = read_seqbegin(&xtime_lock);
-		set_normalized_timespec(&realtime_offset,
-					-wall_to_monotonic.tv_sec,
-					-wall_to_monotonic.tv_nsec);
+		wtm = __get_wall_to_monotonic();
 	} while (read_seqretry(&xtime_lock, seq));
 	} while (read_seqretry(&xtime_lock, seq));
+	set_normalized_timespec(&realtime_offset, -wtm.tv_sec, -wtm.tv_nsec);
 
 
 	base = &__get_cpu_var(hrtimer_bases);
 	base = &__get_cpu_var(hrtimer_bases);
 
 

+ 0 - 16
kernel/time.c

@@ -300,22 +300,6 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
 }
 }
 EXPORT_SYMBOL(timespec_trunc);
 EXPORT_SYMBOL(timespec_trunc);
 
 
-#ifndef CONFIG_GENERIC_TIME
-/*
- * Simulate gettimeofday using do_gettimeofday which only allows a timeval
- * and therefore only yields usec accuracy
- */
-void getnstimeofday(struct timespec *tv)
-{
-	struct timeval x;
-
-	do_gettimeofday(&x);
-	tv->tv_sec = x.tv_sec;
-	tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
-}
-EXPORT_SYMBOL_GPL(getnstimeofday);
-#endif
-
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.

+ 2 - 2
kernel/time/Kconfig

@@ -6,7 +6,7 @@ config TICK_ONESHOT
 
 
 config NO_HZ
 config NO_HZ
 	bool "Tickless System (Dynamic Ticks)"
 	bool "Tickless System (Dynamic Ticks)"
-	depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
+	depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
 	select TICK_ONESHOT
 	select TICK_ONESHOT
 	help
 	help
 	  This option enables a tickless system: timer interrupts will
 	  This option enables a tickless system: timer interrupts will
@@ -15,7 +15,7 @@ config NO_HZ
 
 
 config HIGH_RES_TIMERS
 config HIGH_RES_TIMERS
 	bool "High Resolution Timer Support"
 	bool "High Resolution Timer Support"
-	depends on GENERIC_TIME && GENERIC_CLOCKEVENTS
+	depends on !ARCH_USES_GETTIMEOFFSET && GENERIC_CLOCKEVENTS
 	select TICK_ONESHOT
 	select TICK_ONESHOT
 	help
 	help
 	  This option enables high resolution timer support. If your
 	  This option enables high resolution timer support. If your

+ 26 - 7
kernel/time/clocksource.c

@@ -531,7 +531,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs)
 	return max_nsecs - (max_nsecs >> 5);
 	return max_nsecs - (max_nsecs >> 5);
 }
 }
 
 
-#ifdef CONFIG_GENERIC_TIME
+#ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
 
 
 /**
 /**
  * clocksource_select - Select the best clocksource available
  * clocksource_select - Select the best clocksource available
@@ -577,7 +577,7 @@ static void clocksource_select(void)
 	}
 	}
 }
 }
 
 
-#else /* CONFIG_GENERIC_TIME */
+#else /* !CONFIG_ARCH_USES_GETTIMEOFFSET */
 
 
 static inline void clocksource_select(void) { }
 static inline void clocksource_select(void) { }
 
 
@@ -639,19 +639,18 @@ static void clocksource_enqueue(struct clocksource *cs)
 #define MAX_UPDATE_LENGTH 5 /* Seconds */
 #define MAX_UPDATE_LENGTH 5 /* Seconds */
 
 
 /**
 /**
- * __clocksource_register_scale - Used to install new clocksources
+ * __clocksource_updatefreq_scale - Used update clocksource with new freq
  * @t:		clocksource to be registered
  * @t:		clocksource to be registered
  * @scale:	Scale factor multiplied against freq to get clocksource hz
  * @scale:	Scale factor multiplied against freq to get clocksource hz
  * @freq:	clocksource frequency (cycles per second) divided by scale
  * @freq:	clocksource frequency (cycles per second) divided by scale
  *
  *
- * Returns -EBUSY if registration fails, zero otherwise.
+ * This should only be called from the clocksource->enable() method.
  *
  *
  * This *SHOULD NOT* be called directly! Please use the
  * This *SHOULD NOT* be called directly! Please use the
- * clocksource_register_hz() or clocksource_register_khz helper functions.
+ * clocksource_updatefreq_hz() or clocksource_updatefreq_khz helper functions.
  */
  */
-int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
+void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
 {
 {
-
 	/*
 	/*
 	 * Ideally we want to use  some of the limits used in
 	 * Ideally we want to use  some of the limits used in
 	 * clocksource_max_deferment, to provide a more informed
 	 * clocksource_max_deferment, to provide a more informed
@@ -662,7 +661,27 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
 				      NSEC_PER_SEC/scale,
 				      NSEC_PER_SEC/scale,
 				      MAX_UPDATE_LENGTH*scale);
 				      MAX_UPDATE_LENGTH*scale);
 	cs->max_idle_ns = clocksource_max_deferment(cs);
 	cs->max_idle_ns = clocksource_max_deferment(cs);
+}
+EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
+
+/**
+ * __clocksource_register_scale - Used to install new clocksources
+ * @t:		clocksource to be registered
+ * @scale:	Scale factor multiplied against freq to get clocksource hz
+ * @freq:	clocksource frequency (cycles per second) divided by scale
+ *
+ * Returns -EBUSY if registration fails, zero otherwise.
+ *
+ * This *SHOULD NOT* be called directly! Please use the
+ * clocksource_register_hz() or clocksource_register_khz helper functions.
+ */
+int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
+{
+
+	/* Intialize mult/shift and max_idle_ns */
+	__clocksource_updatefreq_scale(cs, scale, freq);
 
 
+	/* Add clocksource to the clcoksource list */
 	mutex_lock(&clocksource_mutex);
 	mutex_lock(&clocksource_mutex);
 	clocksource_enqueue(cs);
 	clocksource_enqueue(cs);
 	clocksource_select();
 	clocksource_select();

+ 20 - 59
kernel/time/timekeeping.c

@@ -153,8 +153,8 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
  * - wall_to_monotonic is no longer the boot time, getboottime must be
  * - wall_to_monotonic is no longer the boot time, getboottime must be
  * used instead.
  * used instead.
  */
  */
-struct timespec xtime __attribute__ ((aligned (16)));
-struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
+static struct timespec xtime __attribute__ ((aligned (16)));
+static struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
 static struct timespec total_sleep_time;
 static struct timespec total_sleep_time;
 
 
 /*
 /*
@@ -170,11 +170,10 @@ void timekeeping_leap_insert(int leapsecond)
 {
 {
 	xtime.tv_sec += leapsecond;
 	xtime.tv_sec += leapsecond;
 	wall_to_monotonic.tv_sec -= leapsecond;
 	wall_to_monotonic.tv_sec -= leapsecond;
-	update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
+	update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
+			timekeeper.mult);
 }
 }
 
 
-#ifdef CONFIG_GENERIC_TIME
-
 /**
 /**
  * timekeeping_forward_now - update clock to the current time
  * timekeeping_forward_now - update clock to the current time
  *
  *
@@ -328,7 +327,8 @@ int do_settimeofday(struct timespec *tv)
 	timekeeper.ntp_error = 0;
 	timekeeper.ntp_error = 0;
 	ntp_clear();
 	ntp_clear();
 
 
-	update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
+	update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
+				timekeeper.mult);
 
 
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
 
@@ -376,52 +376,6 @@ void timekeeping_notify(struct clocksource *clock)
 	tick_clock_notify();
 	tick_clock_notify();
 }
 }
 
 
-#else /* GENERIC_TIME */
-
-static inline void timekeeping_forward_now(void) { }
-
-/**
- * ktime_get - get the monotonic time in ktime_t format
- *
- * returns the time in ktime_t format
- */
-ktime_t ktime_get(void)
-{
-	struct timespec now;
-
-	ktime_get_ts(&now);
-
-	return timespec_to_ktime(now);
-}
-EXPORT_SYMBOL_GPL(ktime_get);
-
-/**
- * ktime_get_ts - get the monotonic clock in timespec format
- * @ts:		pointer to timespec variable
- *
- * The function calculates the monotonic clock from the realtime
- * clock and the wall_to_monotonic offset and stores the result
- * in normalized timespec format in the variable pointed to by @ts.
- */
-void ktime_get_ts(struct timespec *ts)
-{
-	struct timespec tomono;
-	unsigned long seq;
-
-	do {
-		seq = read_seqbegin(&xtime_lock);
-		getnstimeofday(ts);
-		tomono = wall_to_monotonic;
-
-	} while (read_seqretry(&xtime_lock, seq));
-
-	set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
-				ts->tv_nsec + tomono.tv_nsec);
-}
-EXPORT_SYMBOL_GPL(ktime_get_ts);
-
-#endif /* !GENERIC_TIME */
-
 /**
 /**
  * ktime_get_real - get the real (wall-) time in ktime_t format
  * ktime_get_real - get the real (wall-) time in ktime_t format
  *
  *
@@ -579,9 +533,9 @@ static int timekeeping_resume(struct sys_device *dev)
 
 
 	if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
 	if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
 		ts = timespec_sub(ts, timekeeping_suspend_time);
 		ts = timespec_sub(ts, timekeeping_suspend_time);
-		xtime = timespec_add_safe(xtime, ts);
+		xtime = timespec_add(xtime, ts);
 		wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
 		wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
-		total_sleep_time = timespec_add_safe(total_sleep_time, ts);
+		total_sleep_time = timespec_add(total_sleep_time, ts);
 	}
 	}
 	/* re-base the last cycle value */
 	/* re-base the last cycle value */
 	timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
 	timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
@@ -784,10 +738,11 @@ void update_wall_time(void)
 		return;
 		return;
 
 
 	clock = timekeeper.clock;
 	clock = timekeeper.clock;
-#ifdef CONFIG_GENERIC_TIME
-	offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
-#else
+
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
 	offset = timekeeper.cycle_interval;
 	offset = timekeeper.cycle_interval;
+#else
+	offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
 #endif
 #endif
 	timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
 	timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
 
 
@@ -856,7 +811,8 @@ void update_wall_time(void)
 	}
 	}
 
 
 	/* check to see if there is a new clocksource to use */
 	/* check to see if there is a new clocksource to use */
-	update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
+	update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock,
+				timekeeper.mult);
 }
 }
 
 
 /**
 /**
@@ -887,7 +843,7 @@ EXPORT_SYMBOL_GPL(getboottime);
  */
  */
 void monotonic_to_bootbased(struct timespec *ts)
 void monotonic_to_bootbased(struct timespec *ts)
 {
 {
-	*ts = timespec_add_safe(*ts, total_sleep_time);
+	*ts = timespec_add(*ts, total_sleep_time);
 }
 }
 EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
 EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
 
 
@@ -902,6 +858,11 @@ struct timespec __current_kernel_time(void)
 	return xtime;
 	return xtime;
 }
 }
 
 
+struct timespec __get_wall_to_monotonic(void)
+{
+	return wall_to_monotonic;
+}
+
 struct timespec current_kernel_time(void)
 struct timespec current_kernel_time(void)
 {
 {
 	struct timespec now;
 	struct timespec now;

+ 2 - 2
kernel/trace/Kconfig

@@ -153,7 +153,7 @@ config IRQSOFF_TRACER
 	bool "Interrupts-off Latency Tracer"
 	bool "Interrupts-off Latency Tracer"
 	default n
 	default n
 	depends on TRACE_IRQFLAGS_SUPPORT
 	depends on TRACE_IRQFLAGS_SUPPORT
-	depends on GENERIC_TIME
+	depends on !ARCH_USES_GETTIMEOFFSET
 	select TRACE_IRQFLAGS
 	select TRACE_IRQFLAGS
 	select GENERIC_TRACER
 	select GENERIC_TRACER
 	select TRACER_MAX_TRACE
 	select TRACER_MAX_TRACE
@@ -175,7 +175,7 @@ config IRQSOFF_TRACER
 config PREEMPT_TRACER
 config PREEMPT_TRACER
 	bool "Preemption-off Latency Tracer"
 	bool "Preemption-off Latency Tracer"
 	default n
 	default n
-	depends on GENERIC_TIME
+	depends on !ARCH_USES_GETTIMEOFFSET
 	depends on PREEMPT
 	depends on PREEMPT
 	select GENERIC_TRACER
 	select GENERIC_TRACER
 	select TRACER_MAX_TRACE
 	select TRACER_MAX_TRACE