summaryrefslogtreecommitdiffstats
path: root/kernel/time/timekeeping.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2009-08-14 15:47:32 +0200
committerThomas Gleixner <tglx@linutronix.de>2009-08-15 10:55:47 +0200
commit23970e389e9cee43c4b41023935e1417271708b2 (patch)
treed97d299cf74c44cf7ceb4c04c82dafc451fbbfbb /kernel/time/timekeeping.c
parentd4f587c67fc39e0030ddd718675e252e208da4d7 (diff)
downloadlinux-stable-23970e389e9cee43c4b41023935e1417271708b2.tar.gz
linux-stable-23970e389e9cee43c4b41023935e1417271708b2.tar.bz2
linux-stable-23970e389e9cee43c4b41023935e1417271708b2.zip
timekeeping: Introduce read_boot_clock
Add the new function read_boot_clock to get the exact time the system has been started. For architectures without support for exact boot time a new weak function is added that returns 0. Use the exact boot time to initialize wall_to_monotonic, or xtime if the read_boot_clock returned 0. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Ingo Molnar <mingo@elte.hu> Acked-by: John Stultz <johnstul@us.ibm.com> Cc: Daniel Walker <dwalker@fifo99.com> LKML-Reference: <20090814134811.296703241@de.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r--kernel/time/timekeeping.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index f1a21ce491e6..15e06defca55 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -501,6 +501,21 @@ void __attribute__((weak)) read_persistent_clock(struct timespec *ts)
ts->tv_nsec = 0;
}
+/**
+ * read_boot_clock - Return time of the system start.
+ *
+ * Weak dummy function for arches that do not yet support it.
+ * Function to read the exact time the system has been started.
+ * Returns a timespec with tv_sec=0 and tv_nsec=0 if unsupported.
+ *
+ * XXX - Do be sure to remove it once all arches implement it.
+ */
+void __attribute__((weak)) read_boot_clock(struct timespec *ts)
+{
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+}
+
/*
* timekeeping_init - Initializes the clocksource and common timekeeping values
*/
@@ -508,9 +523,10 @@ void __init timekeeping_init(void)
{
struct clocksource *clock;
unsigned long flags;
- struct timespec now;
+ struct timespec now, boot;
read_persistent_clock(&now);
+ read_boot_clock(&boot);
write_seqlock_irqsave(&xtime_lock, flags);
@@ -525,8 +541,12 @@ void __init timekeeping_init(void)
xtime.tv_nsec = now.tv_nsec;
raw_time.tv_sec = 0;
raw_time.tv_nsec = 0;
+ if (boot.tv_sec == 0 && boot.tv_nsec == 0) {
+ boot.tv_sec = xtime.tv_sec;
+ boot.tv_nsec = xtime.tv_nsec;
+ }
set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
+ -boot.tv_sec, -boot.tv_nsec);
update_xtime_cache(0);
total_sleep_time.tv_sec = 0;
total_sleep_time.tv_nsec = 0;