Commit dc64bef5439c8e1fafea225054da4d8882c9d10c
1 parent
2033b0c330
[S390] Use CONFIG_GENERIC_TIME and define TOD clock source.
Fix too slow clock by using CONFIG_GENERIC_TIME and adding a clock source for the s390 time-of-day clock. As added benefit we get rid of the s390 specific definition of do_gettimeofday and do_settimeofday. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Showing 3 changed files with 24 additions and 68 deletions Side-by-side Diff
arch/s390/Kconfig
arch/s390/defconfig
arch/s390/kernel/time.c
... | ... | @@ -28,6 +28,7 @@ |
28 | 28 | #include <linux/profile.h> |
29 | 29 | #include <linux/timex.h> |
30 | 30 | #include <linux/notifier.h> |
31 | +#include <linux/clocksource.h> | |
31 | 32 | |
32 | 33 | #include <asm/uaccess.h> |
33 | 34 | #include <asm/delay.h> |
... | ... | @@ -82,74 +83,6 @@ |
82 | 83 | xtime->tv_nsec = ((todval * 1000) >> 12); |
83 | 84 | } |
84 | 85 | |
85 | -static inline unsigned long do_gettimeoffset(void) | |
86 | -{ | |
87 | - __u64 now; | |
88 | - | |
89 | - now = (get_clock() - jiffies_timer_cc) >> 12; | |
90 | - now -= (__u64) jiffies * USECS_PER_JIFFY; | |
91 | - return (unsigned long) now; | |
92 | -} | |
93 | - | |
94 | -/* | |
95 | - * This version of gettimeofday has microsecond resolution. | |
96 | - */ | |
97 | -void do_gettimeofday(struct timeval *tv) | |
98 | -{ | |
99 | - unsigned long flags; | |
100 | - unsigned long seq; | |
101 | - unsigned long usec, sec; | |
102 | - | |
103 | - do { | |
104 | - seq = read_seqbegin_irqsave(&xtime_lock, flags); | |
105 | - | |
106 | - sec = xtime.tv_sec; | |
107 | - usec = xtime.tv_nsec / 1000 + do_gettimeoffset(); | |
108 | - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); | |
109 | - | |
110 | - while (usec >= 1000000) { | |
111 | - usec -= 1000000; | |
112 | - sec++; | |
113 | - } | |
114 | - | |
115 | - tv->tv_sec = sec; | |
116 | - tv->tv_usec = usec; | |
117 | -} | |
118 | - | |
119 | -EXPORT_SYMBOL(do_gettimeofday); | |
120 | - | |
121 | -int do_settimeofday(struct timespec *tv) | |
122 | -{ | |
123 | - time_t wtm_sec, sec = tv->tv_sec; | |
124 | - long wtm_nsec, nsec = tv->tv_nsec; | |
125 | - | |
126 | - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) | |
127 | - return -EINVAL; | |
128 | - | |
129 | - write_seqlock_irq(&xtime_lock); | |
130 | - /* This is revolting. We need to set the xtime.tv_nsec | |
131 | - * correctly. However, the value in this location is | |
132 | - * is value at the last tick. | |
133 | - * Discover what correction gettimeofday | |
134 | - * would have done, and then undo it! | |
135 | - */ | |
136 | - nsec -= do_gettimeoffset() * 1000; | |
137 | - | |
138 | - wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); | |
139 | - wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); | |
140 | - | |
141 | - set_normalized_timespec(&xtime, sec, nsec); | |
142 | - set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); | |
143 | - | |
144 | - ntp_clear(); | |
145 | - write_sequnlock_irq(&xtime_lock); | |
146 | - clock_was_set(); | |
147 | - return 0; | |
148 | -} | |
149 | - | |
150 | -EXPORT_SYMBOL(do_settimeofday); | |
151 | - | |
152 | - | |
153 | 86 | #ifdef CONFIG_PROFILING |
154 | 87 | #define s390_do_profile() profile_tick(CPU_PROFILING) |
155 | 88 | #else |
... | ... | @@ -340,6 +273,22 @@ |
340 | 273 | |
341 | 274 | extern void vtime_init(void); |
342 | 275 | |
276 | +static cycle_t read_tod_clock(void) | |
277 | +{ | |
278 | + return get_clock(); | |
279 | +} | |
280 | + | |
281 | +static struct clocksource clocksource_tod = { | |
282 | + .name = "tod", | |
283 | + .rating = 100, | |
284 | + .read = read_tod_clock, | |
285 | + .mask = -1ULL, | |
286 | + .mult = 1000, | |
287 | + .shift = 12, | |
288 | + .is_continuous = 1, | |
289 | +}; | |
290 | + | |
291 | + | |
343 | 292 | /* |
344 | 293 | * Initialize the TOD clock and the CPU timer of |
345 | 294 | * the boot cpu. |
... | ... | @@ -383,6 +332,9 @@ |
383 | 332 | if (register_early_external_interrupt(0x1004, NULL, |
384 | 333 | &ext_int_info_cc) != 0) |
385 | 334 | panic("Couldn't request external interrupt 0x1004"); |
335 | + | |
336 | + if (clocksource_register(&clocksource_tod) != 0) | |
337 | + panic("Could not register TOD clock source"); | |
386 | 338 | |
387 | 339 | init_cpu_timer(); |
388 | 340 |