aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/time.c')
-rw-r--r--arch/s390/kernel/time.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 369ff02c4ab2..6ded50dfa75a 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -253,32 +253,52 @@ void update_vsyscall_tz(void)
253 */ 253 */
254void __init time_init(void) 254void __init time_init(void)
255{ 255{
256 struct timespec ts;
257 unsigned long flags;
258 cycle_t now;
259
256 /* Reset time synchronization interfaces. */ 260 /* Reset time synchronization interfaces. */
257 etr_reset(); 261 etr_reset();
258 stp_reset(); 262 stp_reset();
259 263
260 /* set xtime */
261 tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime);
262 set_normalized_timespec(&wall_to_monotonic,
263 -xtime.tv_sec, -xtime.tv_nsec);
264
265 /* request the clock comparator external interrupt */ 264 /* request the clock comparator external interrupt */
266 if (register_early_external_interrupt(0x1004, 265 if (register_early_external_interrupt(0x1004,
267 clock_comparator_interrupt, 266 clock_comparator_interrupt,
268 &ext_int_info_cc) != 0) 267 &ext_int_info_cc) != 0)
269 panic("Couldn't request external interrupt 0x1004"); 268 panic("Couldn't request external interrupt 0x1004");
270 269
271 if (clocksource_register(&clocksource_tod) != 0)
272 panic("Could not register TOD clock source");
273
274 /* request the timing alert external interrupt */ 270 /* request the timing alert external interrupt */
275 if (register_early_external_interrupt(0x1406, 271 if (register_early_external_interrupt(0x1406,
276 timing_alert_interrupt, 272 timing_alert_interrupt,
277 &ext_int_etr_cc) != 0) 273 &ext_int_etr_cc) != 0)
278 panic("Couldn't request external interrupt 0x1406"); 274 panic("Couldn't request external interrupt 0x1406");
279 275
276 if (clocksource_register(&clocksource_tod) != 0)
277 panic("Could not register TOD clock source");
278
279 /*
280 * The TOD clock is an accurate clock. The xtime should be
281 * initialized in a way that the difference between TOD and
282 * xtime is reasonably small. Too bad that timekeeping_init
283 * sets xtime.tv_nsec to zero. In addition the clock source
284 * change from the jiffies clock source to the TOD clock
285 * source add another error of up to 1/HZ second. The same
286 * function sets wall_to_monotonic to a value that is too
287 * small for /proc/uptime to be accurate.
288 * Reset xtime and wall_to_monotonic to sane values.
289 */
290 write_seqlock_irqsave(&xtime_lock, flags);
291 now = get_clock();
292 tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
293 clocksource_tod.cycle_last = now;
294 clocksource_tod.raw_time = xtime;
295 tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
296 set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
297 write_sequnlock_irqrestore(&xtime_lock, flags);
298
280 /* Enable TOD clock interrupts on the boot cpu. */ 299 /* Enable TOD clock interrupts on the boot cpu. */
281 init_cpu_timer(); 300 init_cpu_timer();
301
282 /* Enable cpu timer interrupts on the boot cpu. */ 302 /* Enable cpu timer interrupts on the boot cpu. */
283 vtime_init(); 303 vtime_init();
284} 304}