aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2009-04-14 09:36:28 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-04-14 09:37:27 -0400
commitb6112ccbff5ec580d46b584ecc3c3a773b830da2 (patch)
tree71553f09a2acfedec85f3c29a1c65e0a257001fb /arch/s390
parent5b409ed17bb32c8316b1f456466c70529454573a (diff)
[S390] add read_persistent_clock
Add a read_persistent_clock function that does not just return 0. Since timekeeping_init calls the function before time_init has been called move reset_tod_clock to early.c to make sure that the TOD clock is running when read_persistent_clock is invoked. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/timex.h5
-rw-r--r--arch/s390/kernel/early.c16
-rw-r--r--arch/s390/kernel/head.S7
-rw-r--r--arch/s390/kernel/time.c28
4 files changed, 35 insertions, 21 deletions
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
index d744c3d62de..cc21e3e20fd 100644
--- a/arch/s390/include/asm/timex.h
+++ b/arch/s390/include/asm/timex.h
@@ -11,6 +11,9 @@
11#ifndef _ASM_S390_TIMEX_H 11#ifndef _ASM_S390_TIMEX_H
12#define _ASM_S390_TIMEX_H 12#define _ASM_S390_TIMEX_H
13 13
14/* The value of the TOD clock for 1.1.1970. */
15#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
16
14/* Inline functions for clock register access. */ 17/* Inline functions for clock register access. */
15static inline int set_clock(__u64 time) 18static inline int set_clock(__u64 time)
16{ 19{
@@ -85,4 +88,6 @@ int get_sync_clock(unsigned long long *clock);
85void init_cpu_timer(void); 88void init_cpu_timer(void);
86unsigned long long monotonic_clock(void); 89unsigned long long monotonic_clock(void);
87 90
91extern u64 sched_clock_base_cc;
92
88#endif 93#endif
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index d4e1e5b6cfd..cf09948faad 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -38,6 +38,21 @@ static unsigned long machine_flags;
38 38
39static void __init setup_boot_command_line(void); 39static void __init setup_boot_command_line(void);
40 40
41/*
42 * Get the TOD clock running.
43 */
44static void __init reset_tod_clock(void)
45{
46 u64 time;
47
48 if (store_clock(&time) == 0)
49 return;
50 /* TOD clock not running. Set the clock to Unix Epoch. */
51 if (set_clock(TOD_UNIX_EPOCH) != 0 || store_clock(&time) != 0)
52 disabled_wait(0);
53
54 sched_clock_base_cc = TOD_UNIX_EPOCH;
55}
41 56
42#ifdef CONFIG_SHARED_KERNEL 57#ifdef CONFIG_SHARED_KERNEL
43int __init savesys_ipl_nss(char *cmd, const int cmdlen); 58int __init savesys_ipl_nss(char *cmd, const int cmdlen);
@@ -372,6 +387,7 @@ static void __init setup_boot_command_line(void)
372 */ 387 */
373void __init startup_init(void) 388void __init startup_init(void)
374{ 389{
390 reset_tod_clock();
375 ipl_save_parameters(); 391 ipl_save_parameters();
376 rescue_initrd(); 392 rescue_initrd();
377 clear_bss_section(); 393 clear_bss_section();
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 1046c2c9f8d..16f8975325e 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -471,6 +471,8 @@ startup:basr %r13,0 # get base
471.LPG0: 471.LPG0:
472 xc 0x200(256),0x200 # partially clear lowcore 472 xc 0x200(256),0x200 # partially clear lowcore
473 xc 0x300(256),0x300 473 xc 0x300(256),0x300
474 l %r1,5f-.LPG0(%r13)
475 stck 0(%r1)
474 476
475#ifndef CONFIG_MARCH_G5 477#ifndef CONFIG_MARCH_G5
476 # check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10} 478 # check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
@@ -496,9 +498,10 @@ startup:basr %r13,0 # get base
496 brct %r0,0b 498 brct %r0,0b
497#endif 499#endif
498 500
499 l %r13,0f-.LPG0(%r13) 501 l %r13,4f-.LPG0(%r13)
500 b 0(%r13) 502 b 0(%r13)
5010: .long startup_continue 5034: .long startup_continue
5045: .long sched_clock_base_cc
502 505
503# 506#
504# params at 10400 (setup.h) 507# params at 10400 (setup.h)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 05f93e77870..369ff02c4ab 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -52,9 +52,6 @@
52#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ) 52#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ)
53#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12) 53#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
54 54
55/* The value of the TOD clock for 1.1.1970. */
56#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
57
58/* 55/*
59 * Create a small time difference between the timer interrupts 56 * Create a small time difference between the timer interrupts
60 * on the different cpus to avoid lock contention. 57 * on the different cpus to avoid lock contention.
@@ -63,9 +60,10 @@
63 60
64#define TICK_SIZE tick 61#define TICK_SIZE tick
65 62
63u64 sched_clock_base_cc = -1; /* Force to data section. */
64
66static ext_int_info_t ext_int_info_cc; 65static ext_int_info_t ext_int_info_cc;
67static ext_int_info_t ext_int_etr_cc; 66static ext_int_info_t ext_int_etr_cc;
68static u64 sched_clock_base_cc;
69 67
70static DEFINE_PER_CPU(struct clock_event_device, comparators); 68static DEFINE_PER_CPU(struct clock_event_device, comparators);
71 69
@@ -195,22 +193,12 @@ static void timing_alert_interrupt(__u16 code)
195static void etr_reset(void); 193static void etr_reset(void);
196static void stp_reset(void); 194static void stp_reset(void);
197 195
198/* 196unsigned long read_persistent_clock(void)
199 * Get the TOD clock running.
200 */
201static u64 __init reset_tod_clock(void)
202{ 197{
203 u64 time; 198 struct timespec ts;
204 199
205 etr_reset(); 200 tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts);
206 stp_reset(); 201 return ts.tv_sec;
207 if (store_clock(&time) == 0)
208 return time;
209 /* TOD clock not running. Set the clock to Unix Epoch. */
210 if (set_clock(TOD_UNIX_EPOCH) != 0 || store_clock(&time) != 0)
211 panic("TOD clock not operational.");
212
213 return TOD_UNIX_EPOCH;
214} 202}
215 203
216static cycle_t read_tod_clock(void) 204static cycle_t read_tod_clock(void)
@@ -265,7 +253,9 @@ void update_vsyscall_tz(void)
265 */ 253 */
266void __init time_init(void) 254void __init time_init(void)
267{ 255{
268 sched_clock_base_cc = reset_tod_clock(); 256 /* Reset time synchronization interfaces. */
257 etr_reset();
258 stp_reset();
269 259
270 /* set xtime */ 260 /* set xtime */
271 tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime); 261 tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime);