diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-04-14 09:36:28 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-04-14 09:37:27 -0400 |
commit | b6112ccbff5ec580d46b584ecc3c3a773b830da2 (patch) | |
tree | 71553f09a2acfedec85f3c29a1c65e0a257001fb | |
parent | 5b409ed17bb32c8316b1f456466c70529454573a (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>
-rw-r--r-- | arch/s390/include/asm/timex.h | 5 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 16 | ||||
-rw-r--r-- | arch/s390/kernel/head.S | 7 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 28 |
4 files changed, 35 insertions, 21 deletions
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index d744c3d62de5..cc21e3e20fd7 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. */ |
15 | static inline int set_clock(__u64 time) | 18 | static inline int set_clock(__u64 time) |
16 | { | 19 | { |
@@ -85,4 +88,6 @@ int get_sync_clock(unsigned long long *clock); | |||
85 | void init_cpu_timer(void); | 88 | void init_cpu_timer(void); |
86 | unsigned long long monotonic_clock(void); | 89 | unsigned long long monotonic_clock(void); |
87 | 90 | ||
91 | extern 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 d4e1e5b6cfda..cf09948faad6 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -38,6 +38,21 @@ static unsigned long machine_flags; | |||
38 | 38 | ||
39 | static void __init setup_boot_command_line(void); | 39 | static void __init setup_boot_command_line(void); |
40 | 40 | ||
41 | /* | ||
42 | * Get the TOD clock running. | ||
43 | */ | ||
44 | static 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 |
43 | int __init savesys_ipl_nss(char *cmd, const int cmdlen); | 58 | int __init savesys_ipl_nss(char *cmd, const int cmdlen); |
@@ -372,6 +387,7 @@ static void __init setup_boot_command_line(void) | |||
372 | */ | 387 | */ |
373 | void __init startup_init(void) | 388 | void __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 1046c2c9f8d1..16f8975325ed 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) |
501 | 0: .long startup_continue | 503 | 4: .long startup_continue |
504 | 5: .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 05f93e77870b..369ff02c4ab2 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 | ||
63 | u64 sched_clock_base_cc = -1; /* Force to data section. */ | ||
64 | |||
66 | static ext_int_info_t ext_int_info_cc; | 65 | static ext_int_info_t ext_int_info_cc; |
67 | static ext_int_info_t ext_int_etr_cc; | 66 | static ext_int_info_t ext_int_etr_cc; |
68 | static u64 sched_clock_base_cc; | ||
69 | 67 | ||
70 | static DEFINE_PER_CPU(struct clock_event_device, comparators); | 68 | static DEFINE_PER_CPU(struct clock_event_device, comparators); |
71 | 69 | ||
@@ -195,22 +193,12 @@ static void timing_alert_interrupt(__u16 code) | |||
195 | static void etr_reset(void); | 193 | static void etr_reset(void); |
196 | static void stp_reset(void); | 194 | static void stp_reset(void); |
197 | 195 | ||
198 | /* | 196 | unsigned long read_persistent_clock(void) |
199 | * Get the TOD clock running. | ||
200 | */ | ||
201 | static 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 | ||
216 | static cycle_t read_tod_clock(void) | 204 | static cycle_t read_tod_clock(void) |
@@ -265,7 +253,9 @@ void update_vsyscall_tz(void) | |||
265 | */ | 253 | */ |
266 | void __init time_init(void) | 254 | void __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); |