diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index d9df913a464d12421c897dc219016e3fd1749ca8..5b7dcd5a0e75b663e709b093bc2f4f21fb3d49b8 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -615,6 +615,11 @@ config VERBOSE_MCHECK_ON
 
 	  Take the default (1) unless you want more control or more info.
 
+config HZ
+	int
+	default 1200 if ALPHA_RAWHIDE
+	default 1024
+
 source "drivers/pci/Kconfig"
 source "drivers/eisa/Kconfig"
 
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 27b082ac7f11e25e8d6b292b54af2c932f259217..ff078e60e76da8f2b9ef0753287b8407d44d277f 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -55,6 +55,10 @@ config CRIS
 	bool
 	default y
 
+config HZ
+	int
+	default 100
+
 source "init/Kconfig"
 
 menu "General setup"
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 96f7d70f4473681dc3f155b31c00215a55267257..9e561ede0925b6928bb44907c1bcde6ee4139d43 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -57,6 +57,10 @@ config ARCH_HAS_ILOG2_U64
 	bool
 	default y
 
+config HZ
+	int
+	default 1000
+
 mainmenu "Fujitsu FR-V Kernel Configuration"
 
 source "init/Kconfig"
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index b4ba4f8b505c2d66f13c906e4a3371efac6bca3e..f69e5ea385588d0c554fe5f0d3ca2ff82f8c2138 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -82,6 +82,10 @@ config PCI
 	bool
 	default n
 
+config HZ
+	int
+	default 100
+
 source "init/Kconfig"
 
 source "arch/h8300/Kconfig.cpu"
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index fe61e00a604f270751b4a4687e93c0297c7bc97a..d4679ab55b969c3fe8bfc4f88dfef02d618e1877 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -38,6 +38,10 @@ config NO_DMA
 config ARCH_SUPPORTS_AOUT
 	def_bool y
 
+config HZ
+	int
+	default 100
+
 source "init/Kconfig"
 
 
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index bcbf3e4ee9d4c5542eff9116c824f0cf2f983605..2b0ed89cd173728ddda8ad3ea201977c5ee0484c 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -55,6 +55,10 @@ config NO_DMA
 config ARCH_SUPPORTS_AOUT
 	def_bool y
 
+config HZ
+	int
+	default 100
+
 mainmenu "Linux/68k Kernel Configuration"
 
 source "init/Kconfig"
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 24f732342d3edca6f31ebd7da4f7d159daac58e8..548a7b321633c670b358f190e2a92a54a694ba45 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -525,6 +525,11 @@ config 4KSTACKS
 	  running more threads on a system and also reduces the pressure
 	  on the VM subsystem for higher order allocations.
 
+config HZ
+	int
+	default 1000 if CLEOPATRA
+	default 100
+
 comment "RAM configuration"
 
 config RAMBASE
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 08821b078eccc20a3b4da15359115b5c2ea3990f..7c674a3503b66c8aa2ced1896bc3df6e2a6e7999 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -30,6 +30,10 @@ config OF
 config ARCH_SUPPORTS_AOUT
 	def_bool y
 
+config HZ
+	int
+	default 100
+
 source "init/Kconfig"
 
 menu "General machine setup"
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 225f30d7cb32477ca1489412df2c72bfd8eec840..7b6d3716efca4a0f370ef848ac8cecbfa0e39eb6 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -215,6 +215,13 @@ menu "Processor type and features"
    	  bool
 	  default !V850E_CACHE && !V850E2_CACHE
 
+   # HZ depends on the platform
+   config HZ
+	  int
+	  default 24  if V850E_SIM || V850E2_SIM85E2
+	  default 122 if V850E2_FPGA85E2C
+	  default 100
+
    #### Misc config
 
    config ROM_KERNEL
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 5d5546ce88fe90b02ff376a633a4933b22639685..fd36764d7fb72358a65a3551ad9a0faf7b4a70e1 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -49,6 +49,10 @@ config ARCH_HAS_ILOG2_U64
 config NO_IOPORT
 	def_bool y
 
+config HZ
+	int
+	default 100
+
 source "init/Kconfig"
 
 menu "Processor type and features"
diff --git a/include/asm-alpha/param.h b/include/asm-alpha/param.h
index 214e7996346f25e890c9221c35fac975f4e7ee78..0982f1d39499fbe337b440cc995913e2fbbb792d 100644
--- a/include/asm-alpha/param.h
+++ b/include/asm-alpha/param.h
@@ -5,15 +5,7 @@
    hardware ignores reprogramming.  We also need userland buy-in to the 
    change in HZ, since this is visible in the wait4 resources etc.  */
 
-
-#ifndef HZ
-# ifndef CONFIG_ALPHA_RAWHIDE
-#  define HZ	1024
-# else
-#  define HZ	1200
-# endif
-#endif
-
+#define HZ		CONFIG_HZ
 #define USER_HZ		HZ
 
 #define EXEC_PAGESIZE	8192
diff --git a/include/asm-cris/param.h b/include/asm-cris/param.h
index b249726398320ffcc9b12d56fc227dc3be6929e5..0e47994e40be536de84bcb6ed85a37770fb6015a 100644
--- a/include/asm-cris/param.h
+++ b/include/asm-cris/param.h
@@ -3,7 +3,7 @@
 
 /* Currently we assume that HZ=100 is good for CRIS. */
 #ifdef __KERNEL__
-# define HZ		100		/* Internal kernel timer frequency */
+# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100		/* .. some user interfaces are in "ticks" */
 # define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
 #endif
diff --git a/include/asm-frv/param.h b/include/asm-frv/param.h
index 365653b1726c18892a3a1ea5efb760b50f64ddaa..6859dd503ed366910cfe0fa85e7c0acf53e7f525 100644
--- a/include/asm-frv/param.h
+++ b/include/asm-frv/param.h
@@ -2,7 +2,7 @@
 #define _ASM_PARAM_H
 
 #ifdef __KERNEL__
-#define HZ		1000		/* Internal kernel timer frequency */
+#define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 #define USER_HZ		100		/* .. some user interfaces are in "ticks" */
 #define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
 #endif
diff --git a/include/asm-h8300/param.h b/include/asm-h8300/param.h
index c25806ed1fb368d2581b00f853bb4d55ade94b9d..04f64f1003792b77c4a6be5a8da51f3f7b2e9b93 100644
--- a/include/asm-h8300/param.h
+++ b/include/asm-h8300/param.h
@@ -3,7 +3,7 @@
 
 
 #ifndef HZ
-#define HZ 100
+#define HZ CONFIG_HZ
 #endif
 
 #ifdef __KERNEL__
diff --git a/include/asm-m32r/param.h b/include/asm-m32r/param.h
index 3e14026e39cdaf2a479d1a09dabaf9c2d6b514b8..94c770196048335767a40f9fd8fd649d11f1effb 100644
--- a/include/asm-m32r/param.h
+++ b/include/asm-m32r/param.h
@@ -2,7 +2,7 @@
 #define _ASM_M32R_PARAM_H
 
 #ifdef __KERNEL__
-# define HZ		100		/* Internal kernel timer frequency */
+# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100		/* .. some user interfaces are in "ticks" */
 # define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
 #endif
diff --git a/include/asm-m68k/param.h b/include/asm-m68k/param.h
index 60f409d81658193e36e1f077d1e643a1e390b191..536a27888358d59a15e6f4342513a3fb04ebb3be 100644
--- a/include/asm-m68k/param.h
+++ b/include/asm-m68k/param.h
@@ -2,7 +2,7 @@
 #define _M68K_PARAM_H
 
 #ifdef __KERNEL__
-# define HZ		100		/* Internal kernel timer frequency */
+# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100		/* .. some user interfaces are in "ticks" */
 # define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */
 #endif
diff --git a/include/asm-m68knommu/param.h b/include/asm-m68knommu/param.h
index 4c9904d6512ed6e278184fa56375d072239f0f07..96c45101832491ecbb7e0cabdb5b49d49f5fa5d2 100644
--- a/include/asm-m68knommu/param.h
+++ b/include/asm-m68knommu/param.h
@@ -1,13 +1,7 @@
 #ifndef _M68KNOMMU_PARAM_H
 #define _M68KNOMMU_PARAM_H
 
-
-#if defined(CONFIG_CLEOPATRA)
-#define	HZ 1000
-#endif
-#ifndef HZ
-#define	HZ 100
-#endif
+#define HZ CONFIG_HZ
 
 #ifdef __KERNEL__
 #define	USER_HZ		HZ
diff --git a/include/asm-sparc/param.h b/include/asm-sparc/param.h
index beaf02d364f231374f0f6c602f68839754b2cec2..86ba59af9d2c7d44d775a64d3c548d53622228a2 100644
--- a/include/asm-sparc/param.h
+++ b/include/asm-sparc/param.h
@@ -3,7 +3,7 @@
 #define _ASMSPARC_PARAM_H
 
 #ifdef __KERNEL__
-# define HZ		100	/* Internal kernel timer frequency */
+# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100	/* .. some user interfaces are in "ticks" */
 # define CLOCKS_PER_SEC (USER_HZ)
 #endif
diff --git a/include/asm-v850/anna.h b/include/asm-v850/anna.h
index 3be77d5ecfce38c9d9efec628c529582083ef92f..cd5eaee103b0f8069bf3de282cbb4ac9d34ba5ef 100644
--- a/include/asm-v850/anna.h
+++ b/include/asm-v850/anna.h
@@ -134,10 +134,4 @@ extern void anna_uart_pre_configure (unsigned chan,
 #define V850E_TIMER_D_TMCD_CS_MIN	1 /* min 2^1 divider */
 
 
-/* For <asm/param.h> */
-#ifndef HZ
-#define HZ	100
-#endif
-
-
 #endif /* __V850_ANNA_H__ */
diff --git a/include/asm-v850/as85ep1.h b/include/asm-v850/as85ep1.h
index 659bc910ffd72f060012131b8c6fc05775e3299c..5a5ca9073d0931027a470091ecec0ac81ceddb4d 100644
--- a/include/asm-v850/as85ep1.h
+++ b/include/asm-v850/as85ep1.h
@@ -149,10 +149,4 @@ extern void as85ep1_uart_pre_configure (unsigned chan,
 #define V850E_TIMER_D_TMCD_CS_MIN	2 /* min 2^2 divider */
 
 
-/* For <asm/param.h> */
-#ifndef HZ
-#define HZ	100
-#endif
-
-
 #endif /* __V850_AS85EP1_H__ */
diff --git a/include/asm-v850/fpga85e2c.h b/include/asm-v850/fpga85e2c.h
index d32f04504b135073de1410fc14e8ea103184d6a5..23aae666c718ce62ae1f18129d6eec12021a3f5b 100644
--- a/include/asm-v850/fpga85e2c.h
+++ b/include/asm-v850/fpga85e2c.h
@@ -79,10 +79,4 @@ extern char _r0_ram;
 #endif
 
 
-/* For <asm/param.h> */
-#ifndef HZ
-#define HZ			122 /* actually, 8.192ms ticks =~ 122.07 */
-#endif
-
-
 #endif /* __V850_FPGA85E2C_H__ */
diff --git a/include/asm-v850/param.h b/include/asm-v850/param.h
index 3c65bd573782d34e060d52299bfcc5a4cd7b37bb..281832690290536007c861a8362634cb673b7f43 100644
--- a/include/asm-v850/param.h
+++ b/include/asm-v850/param.h
@@ -23,8 +23,7 @@
 #define MAXHOSTNAMELEN	64	/* max length of hostname */
 
 #ifdef __KERNEL__
-#include <asm/machdep.h>	/* For HZ */
-
+# define HZ		CONFIG_HZ
 # define USER_HZ	100
 # define CLOCKS_PER_SEC	USER_HZ
 #endif
diff --git a/include/asm-v850/rte_cb.h b/include/asm-v850/rte_cb.h
index e85d261b79bf0ee140ab1f5f349b6b25e100d25d..db9879f00aa7b9adacca1a8b72a7f21126bdbb59 100644
--- a/include/asm-v850/rte_cb.h
+++ b/include/asm-v850/rte_cb.h
@@ -69,12 +69,6 @@
 #endif /* CONFIG_RTE_MB_A_PCI */
 
 
-/* For <asm/param.h> */
-#ifndef HZ
-#define HZ	100
-#endif
-
-
 #ifndef __ASSEMBLY__
 extern void rte_cb_early_init (void);
 extern void rte_cb_init_irqs (void);
diff --git a/include/asm-v850/sim.h b/include/asm-v850/sim.h
index 10236abbe9be7aca7fdfb04c4f28a1b1d3ee0aad..026932d476cd9036aa57208e780076687f6ba99b 100644
--- a/include/asm-v850/sim.h
+++ b/include/asm-v850/sim.h
@@ -40,11 +40,6 @@
 #define R0_RAM_ADDR		0xFFFFF000
 
 
-/* For <asm/param.h> */
-#ifndef HZ
-#define HZ			24	/* Minimum supported frequency.  */
-#endif
-
 /* For <asm/irq.h> */
 #define NUM_CPU_IRQS		6
 
diff --git a/include/asm-v850/sim85e2.h b/include/asm-v850/sim85e2.h
index 17dd4fa318e65d4eb17ecbfb0f824b525f139eeb..8b4d6974066c2d624f3deb58ff32c17e5950682b 100644
--- a/include/asm-v850/sim85e2.h
+++ b/include/asm-v850/sim85e2.h
@@ -66,10 +66,4 @@
 #define R0_RAM_ADDR		0xFFFFE000
 
 
-/* For <asm/param.h> */
-#ifndef HZ
-#define HZ			24	/* Minimum supported frequency.  */
-#endif
-
-
 #endif /* __V850_SIM85E2_H__ */
diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h
index ce3a336cad07c188ebe7dc10805c2d6c060212a8..82ad34d92d359746de497c9a680306a7a661f45f 100644
--- a/include/asm-xtensa/param.h
+++ b/include/asm-xtensa/param.h
@@ -12,7 +12,7 @@
 #define _XTENSA_PARAM_H
 
 #ifdef __KERNEL__
-# define HZ		100		/* internal timer frequency */
+# define HZ		CONFIG_HZ	/* internal timer frequency */
 # define USER_HZ	100		/* for user interfaces in "ticks" */
 # define CLOCKS_PER_SEC (USER_HZ)	/* frequnzy at which times() counts */
 #endif
diff --git a/kernel/Makefile b/kernel/Makefile
index 60cd39c84e6d47bce185e616a10bf790c7becfbb..6c584c55a6e9e8f164fa949b8a5c5ed8054ed9f8 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -91,3 +91,11 @@ quiet_cmd_ikconfiggz = IKCFG   $@
 targets += config_data.h
 $(obj)/config_data.h: $(obj)/config_data.gz FORCE
 	$(call if_changed,ikconfiggz)
+
+$(obj)/time.o: $(obj)/timeconst.h
+
+quiet_cmd_timeconst  = TIMEC   $@
+      cmd_timeconst  = $(PERL) $< $(CONFIG_HZ) > $@
+targets += timeconst.h
+$(obj)/timeconst.h: $(src)/timeconst.pl FORCE
+	$(call if_changed,timeconst)
diff --git a/kernel/time.c b/kernel/time.c
index 3b705ecc3fb7843eff331cbf077f314c22a8f071..a5ec013b6c807be91292179023406e995f765fb2 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -39,6 +39,8 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
+#include "timeconst.h"
+
 /*
  * The timezone where the local system is located.  Used as a default by some
  * programs who obtain this value by using gettimeofday.
@@ -93,7 +95,8 @@ asmlinkage long sys_stime(time_t __user *tptr)
 
 #endif /* __ARCH_WANT_SYS_TIME */
 
-asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __user *tz)
+asmlinkage long sys_gettimeofday(struct timeval __user *tv,
+				 struct timezone __user *tz)
 {
 	if (likely(tv != NULL)) {
 		struct timeval ktv;
@@ -118,7 +121,7 @@ asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __us
  * hard to make the program warp the clock precisely n hours)  or
  * compile in the timezone information into the kernel.  Bad, bad....
  *
- *              				- TYT, 1992-01-01
+ *						- TYT, 1992-01-01
  *
  * The best thing to do is to keep the CMOS clock in universal time (UTC)
  * as real UNIX machines always do it. This avoids all headaches about
@@ -240,7 +243,11 @@ unsigned int inline jiffies_to_msecs(const unsigned long j)
 #elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
 	return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
 #else
-	return (j * MSEC_PER_SEC) / HZ;
+# if BITS_PER_LONG == 32
+	return ((u64)HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32;
+# else
+	return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN;
+# endif
 #endif
 }
 EXPORT_SYMBOL(jiffies_to_msecs);
@@ -252,7 +259,11 @@ unsigned int inline jiffies_to_usecs(const unsigned long j)
 #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
 	return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
 #else
-	return (j * USEC_PER_SEC) / HZ;
+# if BITS_PER_LONG == 32
+	return ((u64)HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32;
+# else
+	return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN;
+# endif
 #endif
 }
 EXPORT_SYMBOL(jiffies_to_usecs);
@@ -352,7 +363,7 @@ EXPORT_SYMBOL(mktime);
  * normalize to the timespec storage format
  *
  * Note: The tv_nsec part is always in the range of
- * 	0 <= tv_nsec < NSEC_PER_SEC
+ *	0 <= tv_nsec < NSEC_PER_SEC
  * For negative values only the tv_sec field is negative !
  */
 void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
@@ -453,12 +464,13 @@ unsigned long msecs_to_jiffies(const unsigned int m)
 	/*
 	 * Generic case - multiply, round and divide. But first
 	 * check that if we are doing a net multiplication, that
-	 * we wouldnt overflow:
+	 * we wouldn't overflow:
 	 */
 	if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
 		return MAX_JIFFY_OFFSET;
 
-	return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC;
+	return ((u64)MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
+		>> MSEC_TO_HZ_SHR32;
 #endif
 }
 EXPORT_SYMBOL(msecs_to_jiffies);
@@ -472,7 +484,8 @@ unsigned long usecs_to_jiffies(const unsigned int u)
 #elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
 	return u * (HZ / USEC_PER_SEC);
 #else
-	return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC;
+	return ((u64)USEC_TO_HZ_MUL32 * u + USEC_TO_HZ_ADJ32)
+		>> USEC_TO_HZ_SHR32;
 #endif
 }
 EXPORT_SYMBOL(usecs_to_jiffies);
diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl
new file mode 100644
index 0000000000000000000000000000000000000000..62b1287932ed4c8506ad2b8151c2dd778262b36e
--- /dev/null
+++ b/kernel/timeconst.pl
@@ -0,0 +1,402 @@
+#!/usr/bin/perl
+# -----------------------------------------------------------------------
+#
+#   Copyright 2007 rPath, Inc. - All Rights Reserved
+#
+#   This file is part of the Linux kernel, and is made available under
+#   the terms of the GNU General Public License version 2 or (at your
+#   option) any later version; incorporated herein by reference.
+#
+# -----------------------------------------------------------------------
+#
+
+#
+# Usage: timeconst.pl HZ > timeconst.h
+#
+
+# Precomputed values for systems without Math::BigInt
+# Generated by:
+# timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
+%canned_values = (
+	24 => [
+		'0xa6aaaaab','0x2aaaaaa',26,
+		'0xa6aaaaaaaaaaaaab','0x2aaaaaaaaaaaaaa',58,
+		125,3,
+		'0xc49ba5e4','0x1fbe76c8b4',37,
+		'0xc49ba5e353f7ceda','0x1fbe76c8b439581062',69,
+		3,125,
+		'0xa2c2aaab','0xaaaa',16,
+		'0xa2c2aaaaaaaaaaab','0xaaaaaaaaaaaa',48,
+		125000,3,
+		'0xc9539b89','0x7fffbce4217d',47,
+		'0xc9539b8887229e91','0x7fffbce4217d2849cb25',79,
+		3,125000,
+	], 32 => [
+		'0xfa000000','0x6000000',27,
+		'0xfa00000000000000','0x600000000000000',59,
+		125,4,
+		'0x83126e98','0xfdf3b645a',36,
+		'0x83126e978d4fdf3c','0xfdf3b645a1cac0831',68,
+		4,125,
+		'0xf4240000','0x0',17,
+		'0xf424000000000000','0x0',49,
+		31250,1,
+		'0x8637bd06','0x3fff79c842fa',46,
+		'0x8637bd05af6c69b6','0x3fff79c842fa5093964a',78,
+		1,31250,
+	], 48 => [
+		'0xa6aaaaab','0x6aaaaaa',27,
+		'0xa6aaaaaaaaaaaaab','0x6aaaaaaaaaaaaaa',59,
+		125,6,
+		'0xc49ba5e4','0xfdf3b645a',36,
+		'0xc49ba5e353f7ceda','0xfdf3b645a1cac0831',68,
+		6,125,
+		'0xa2c2aaab','0x15555',17,
+		'0xa2c2aaaaaaaaaaab','0x1555555555555',49,
+		62500,3,
+		'0xc9539b89','0x3fffbce4217d',46,
+		'0xc9539b8887229e91','0x3fffbce4217d2849cb25',78,
+		3,62500,
+	], 64 => [
+		'0xfa000000','0xe000000',28,
+		'0xfa00000000000000','0xe00000000000000',60,
+		125,8,
+		'0x83126e98','0x7ef9db22d',35,
+		'0x83126e978d4fdf3c','0x7ef9db22d0e560418',67,
+		8,125,
+		'0xf4240000','0x0',18,
+		'0xf424000000000000','0x0',50,
+		15625,1,
+		'0x8637bd06','0x1fff79c842fa',45,
+		'0x8637bd05af6c69b6','0x1fff79c842fa5093964a',77,
+		1,15625,
+	], 100 => [
+		'0xa0000000','0x0',28,
+		'0xa000000000000000','0x0',60,
+		10,1,
+		'0xcccccccd','0x733333333',35,
+		'0xcccccccccccccccd','0x73333333333333333',67,
+		1,10,
+		'0x9c400000','0x0',18,
+		'0x9c40000000000000','0x0',50,
+		10000,1,
+		'0xd1b71759','0x1fff2e48e8a7',45,
+		'0xd1b71758e219652c','0x1fff2e48e8a71de69ad4',77,
+		1,10000,
+	], 122 => [
+		'0x8325c53f','0xfbcda3a',28,
+		'0x8325c53ef368eb05','0xfbcda3ac10c9714',60,
+		500,61,
+		'0xf9db22d1','0x7fbe76c8b',35,
+		'0xf9db22d0e560418a','0x7fbe76c8b43958106',67,
+		61,500,
+		'0x8012e2a0','0x3ef36',18,
+		'0x8012e29f79b47583','0x3ef368eb04325',50,
+		500000,61,
+		'0xffda4053','0x1ffffbce4217',45,
+		'0xffda4052d666a983','0x1ffffbce4217d2849cb2',77,
+		61,500000,
+	], 128 => [
+		'0xfa000000','0x1e000000',29,
+		'0xfa00000000000000','0x1e00000000000000',61,
+		125,16,
+		'0x83126e98','0x3f7ced916',34,
+		'0x83126e978d4fdf3c','0x3f7ced916872b020c',66,
+		16,125,
+		'0xf4240000','0x40000',19,
+		'0xf424000000000000','0x4000000000000',51,
+		15625,2,
+		'0x8637bd06','0xfffbce4217d',44,
+		'0x8637bd05af6c69b6','0xfffbce4217d2849cb25',76,
+		2,15625,
+	], 200 => [
+		'0xa0000000','0x0',29,
+		'0xa000000000000000','0x0',61,
+		5,1,
+		'0xcccccccd','0x333333333',34,
+		'0xcccccccccccccccd','0x33333333333333333',66,
+		1,5,
+		'0x9c400000','0x0',19,
+		'0x9c40000000000000','0x0',51,
+		5000,1,
+		'0xd1b71759','0xfff2e48e8a7',44,
+		'0xd1b71758e219652c','0xfff2e48e8a71de69ad4',76,
+		1,5000,
+	], 250 => [
+		'0x80000000','0x0',29,
+		'0x8000000000000000','0x0',61,
+		4,1,
+		'0x80000000','0x180000000',33,
+		'0x8000000000000000','0x18000000000000000',65,
+		1,4,
+		'0xfa000000','0x0',20,
+		'0xfa00000000000000','0x0',52,
+		4000,1,
+		'0x83126e98','0x7ff7ced9168',43,
+		'0x83126e978d4fdf3c','0x7ff7ced916872b020c4',75,
+		1,4000,
+	], 256 => [
+		'0xfa000000','0x3e000000',30,
+		'0xfa00000000000000','0x3e00000000000000',62,
+		125,32,
+		'0x83126e98','0x1fbe76c8b',33,
+		'0x83126e978d4fdf3c','0x1fbe76c8b43958106',65,
+		32,125,
+		'0xf4240000','0xc0000',20,
+		'0xf424000000000000','0xc000000000000',52,
+		15625,4,
+		'0x8637bd06','0x7ffde7210be',43,
+		'0x8637bd05af6c69b6','0x7ffde7210be9424e592',75,
+		4,15625,
+	], 300 => [
+		'0xd5555556','0x2aaaaaaa',30,
+		'0xd555555555555556','0x2aaaaaaaaaaaaaaa',62,
+		10,3,
+		'0x9999999a','0x1cccccccc',33,
+		'0x999999999999999a','0x1cccccccccccccccc',65,
+		3,10,
+		'0xd0555556','0xaaaaa',20,
+		'0xd055555555555556','0xaaaaaaaaaaaaa',52,
+		10000,3,
+		'0x9d495183','0x7ffcb923a29',43,
+		'0x9d495182a9930be1','0x7ffcb923a29c779a6b5',75,
+		3,10000,
+	], 512 => [
+		'0xfa000000','0x7e000000',31,
+		'0xfa00000000000000','0x7e00000000000000',63,
+		125,64,
+		'0x83126e98','0xfdf3b645',32,
+		'0x83126e978d4fdf3c','0xfdf3b645a1cac083',64,
+		64,125,
+		'0xf4240000','0x1c0000',21,
+		'0xf424000000000000','0x1c000000000000',53,
+		15625,8,
+		'0x8637bd06','0x3ffef39085f',42,
+		'0x8637bd05af6c69b6','0x3ffef39085f4a1272c9',74,
+		8,15625,
+	], 1000 => [
+		'0x80000000','0x0',31,
+		'0x8000000000000000','0x0',63,
+		1,1,
+		'0x80000000','0x0',31,
+		'0x8000000000000000','0x0',63,
+		1,1,
+		'0xfa000000','0x0',22,
+		'0xfa00000000000000','0x0',54,
+		1000,1,
+		'0x83126e98','0x1ff7ced9168',41,
+		'0x83126e978d4fdf3c','0x1ff7ced916872b020c4',73,
+		1,1000,
+	], 1024 => [
+		'0xfa000000','0xfe000000',32,
+		'0xfa00000000000000','0xfe00000000000000',64,
+		125,128,
+		'0x83126e98','0x7ef9db22',31,
+		'0x83126e978d4fdf3c','0x7ef9db22d0e56041',63,
+		128,125,
+		'0xf4240000','0x3c0000',22,
+		'0xf424000000000000','0x3c000000000000',54,
+		15625,16,
+		'0x8637bd06','0x1fff79c842f',41,
+		'0x8637bd05af6c69b6','0x1fff79c842fa5093964',73,
+		16,15625,
+	], 1200 => [
+		'0xd5555556','0xd5555555',32,
+		'0xd555555555555556','0xd555555555555555',64,
+		5,6,
+		'0x9999999a','0x66666666',31,
+		'0x999999999999999a','0x6666666666666666',63,
+		6,5,
+		'0xd0555556','0x2aaaaa',22,
+		'0xd055555555555556','0x2aaaaaaaaaaaaa',54,
+		2500,3,
+		'0x9d495183','0x1ffcb923a29',41,
+		'0x9d495182a9930be1','0x1ffcb923a29c779a6b5',73,
+		3,2500,
+	]
+);
+
+$has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
+
+sub bint($)
+{
+	my($x) = @_;
+	return Math::BigInt->new($x);
+}
+
+#
+# Constants for division by reciprocal multiplication.
+# (bits, numerator, denominator)
+#
+sub fmul($$$)
+{
+	my ($b,$n,$d) = @_;
+
+	$n = bint($n);
+	$d = bint($d);
+
+	return scalar (($n << $b)+$d-bint(1))/$d;
+}
+
+sub fadj($$$)
+{
+	my($b,$n,$d) = @_;
+
+	$n = bint($n);
+	$d = bint($d);
+
+	$d = $d/bgcd($n, $d);
+	return scalar (($d-bint(1)) << $b)/$d;
+}
+
+sub fmuls($$$) {
+	my($b,$n,$d) = @_;
+	my($s,$m);
+	my($thres) = bint(1) << ($b-1);
+
+	$n = bint($n);
+	$d = bint($d);
+
+	for ($s = 0; 1; $s++) {
+		$m = fmul($s,$n,$d);
+		return $s if ($m >= $thres);
+	}
+	return 0;
+}
+
+# Provides mul, adj, and shr factors for a specific
+# (bit, time, hz) combination
+sub muladj($$$) {
+	my($b, $t, $hz) = @_;
+	my $s = fmuls($b, $t, $hz);
+	my $m = fmul($s, $t, $hz);
+	my $a = fadj($s, $t, $hz);
+	return ($m->as_hex(), $a->as_hex(), $s);
+}
+
+# Provides numerator, denominator values
+sub numden($$) {
+	my($n, $d) = @_;
+	my $g = bgcd($n, $d);
+	return ($n/$g, $d/$g);
+}
+
+# All values for a specific (time, hz) combo
+sub conversions($$) {
+	my ($t, $hz) = @_;
+	my @val = ();
+
+	# HZ_TO_xx
+	push(@val, muladj(32, $t, $hz));
+	push(@val, muladj(64, $t, $hz));
+	push(@val, numden($t, $hz));
+
+	# xx_TO_HZ
+	push(@val, muladj(32, $hz, $t));
+	push(@val, muladj(64, $hz, $t));
+	push(@val, numden($hz, $t));
+
+	return @val;
+}
+
+sub compute_values($) {
+	my($hz) = @_;
+	my @val = ();
+	my $s, $m, $a, $g;
+
+	if (!$has_bigint) {
+		die "$0: HZ == $hz not canned and ".
+		    "Math::BigInt not available\n";
+	}
+
+	# MSEC conversions
+	push(@val, conversions(1000, $hz));
+
+	# USEC conversions
+	push(@val, conversions(1000000, $hz));
+
+	return @val;
+}
+
+sub output($@)
+{
+	my($hz, @val) = @_;
+	my $pfx, $bit, $suf, $s, $m, $a;
+
+	print "/* Automatically generated by kernel/timeconst.pl */\n";
+	print "/* Conversion constants for HZ == $hz */\n";
+	print "\n";
+	print "#ifndef KERNEL_TIMECONST_H\n";
+	print "#define KERNEL_TIMECONST_H\n";
+	print "\n";
+
+	print "#include <linux/param.h>\n";
+
+	print "\n";
+	print "#if HZ != $hz\n";
+	print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
+	print "#endif\n";
+	print "\n";
+
+	foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
+		      'USEC_TO_HZ','HZ_TO_USEC') {
+		foreach $bit (32, 64) {
+			foreach $suf ('MUL', 'ADJ', 'SHR') {
+				printf "#define %-23s %s\n",
+					"${pfx}_$suf$bit", shift(@val);
+			}
+		}
+		foreach $suf ('NUM', 'DEN') {
+			printf "#define %-23s %s\n",
+				"${pfx}_$suf", shift(@val);
+		}
+	}
+
+	print "\n";
+	print "#endif /* KERNEL_TIMECONST_H */\n";
+}
+
+($hz) = @ARGV;
+
+# Use this to generate the %canned_values structure
+if ($hz eq '--can') {
+	shift(@ARGV);
+	@hzlist = sort {$a <=> $b} (@ARGV);
+
+	print "# Precomputed values for systems without Math::BigInt\n";
+	print "# Generated by:\n";
+	print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
+	print "\%canned_values = (\n";
+	my $pf = "\t";
+	foreach $hz (@hzlist) {
+		my @values = compute_values($hz);
+		print "$pf$hz => [\n";
+		while (scalar(@values)) {
+			my $bit;
+			foreach $bit (32, 64) {
+				my $m = shift(@values);
+				my $a = shift(@values);
+				my $s = shift(@values);
+				print "\t\t\'",$m,"\',\'",$a,"\',",$s,",\n";
+			}
+			my $n = shift(@values);
+			my $d = shift(@values);
+			print "\t\t",$n,',',$d,",\n";
+		}
+		print "\t]";
+		$pf = ', ';
+	}
+	print "\n);\n";
+} else {
+	$hz += 0;			# Force to number
+	if ($hz < 1) {
+		die "Usage: $0 HZ\n";
+	}
+
+	@val = @{$canned_values{$hz}};
+	if (!defined(@val)) {
+		@val = compute_values($hz);
+	}
+	output($hz, @val);
+}
+exit 0;