diff options
| -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); |
