summaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/time.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-12-16 14:43:57 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-12-16 14:43:57 -0800
commit48ea753075aa15699bd5fac26faa08431aaa697b (patch)
tree4ce1b1890dc687cb1cf77f98e7a95b94c7ef3a93 /arch/ia64/kernel/time.c
parent7c3dbbe982ac85837f1da150ea9539a9e9a12557 (diff)
parentdc86e88c2bb8a7603ee175fbb6a9e92cf3293dd8 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
Diffstat (limited to 'arch/ia64/kernel/time.c')
-rw-r--r--arch/ia64/kernel/time.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 5b7e736f3b49..028a2b95936c 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -249,3 +249,32 @@ time_init (void)
*/
set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
}
+
+#define SMALLUSECS 100
+
+void
+udelay (unsigned long usecs)
+{
+ unsigned long start;
+ unsigned long cycles;
+ unsigned long smallusecs;
+
+ /*
+ * Execute the non-preemptible delay loop (because the ITC might
+ * not be synchronized between CPUS) in relatively short time
+ * chunks, allowing preemption between the chunks.
+ */
+ while (usecs > 0) {
+ smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs;
+ preempt_disable();
+ cycles = smallusecs*local_cpu_data->cyc_per_usec;
+ start = ia64_get_itc();
+
+ while (ia64_get_itc() - start < cycles)
+ cpu_relax();
+
+ preempt_enable();
+ usecs -= smallusecs;
+ }
+}
+EXPORT_SYMBOL(udelay);