diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2008-05-01 07:34:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-01 11:03:59 -0400 |
commit | 153b5d054ac2d98ea0d86504884326b6777f683d (patch) | |
tree | 0512b4239959814a6cc6aa6c9e77abc36d3ab2f0 | |
parent | 9f14f669d18477fe3df071e2fa4da36c00acee8e (diff) |
ntp: support for TAI
This adds support for setting the TAI value (International Atomic Time). The
value is reported back to userspace via timex (as we don't have a
ntp_gettime() syscall).
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/linux/compat.h | 3 | ||||
-rw-r--r-- | include/linux/timex.h | 5 | ||||
-rw-r--r-- | kernel/compat.c | 3 | ||||
-rw-r--r-- | kernel/time/ntp.c | 7 |
4 files changed, 15 insertions, 3 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h index 8fa7857e153b..cf8d11cad5ae 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -65,10 +65,11 @@ struct compat_timex { | |||
65 | compat_long_t calcnt; | 65 | compat_long_t calcnt; |
66 | compat_long_t errcnt; | 66 | compat_long_t errcnt; |
67 | compat_long_t stbcnt; | 67 | compat_long_t stbcnt; |
68 | compat_int_t tai; | ||
68 | 69 | ||
69 | compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; | 70 | compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; |
70 | compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; | 71 | compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; |
71 | compat_int_t :32; compat_int_t :32; compat_int_t :32; compat_int_t :32; | 72 | compat_int_t :32; compat_int_t :32; compat_int_t :32; |
72 | }; | 73 | }; |
73 | 74 | ||
74 | #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) | 75 | #define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW) |
diff --git a/include/linux/timex.h b/include/linux/timex.h index 9fbdd12a52f1..6ff92237759a 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -121,9 +121,11 @@ struct timex { | |||
121 | long errcnt; /* calibration errors (ro) */ | 121 | long errcnt; /* calibration errors (ro) */ |
122 | long stbcnt; /* stability limit exceeded (ro) */ | 122 | long stbcnt; /* stability limit exceeded (ro) */ |
123 | 123 | ||
124 | int tai; /* TAI offset (ro) */ | ||
125 | |||
124 | int :32; int :32; int :32; int :32; | 126 | int :32; int :32; int :32; int :32; |
125 | int :32; int :32; int :32; int :32; | 127 | int :32; int :32; int :32; int :32; |
126 | int :32; int :32; int :32; int :32; | 128 | int :32; int :32; int :32; |
127 | }; | 129 | }; |
128 | 130 | ||
129 | /* | 131 | /* |
@@ -135,6 +137,7 @@ struct timex { | |||
135 | #define ADJ_ESTERROR 0x0008 /* estimated time error */ | 137 | #define ADJ_ESTERROR 0x0008 /* estimated time error */ |
136 | #define ADJ_STATUS 0x0010 /* clock status */ | 138 | #define ADJ_STATUS 0x0010 /* clock status */ |
137 | #define ADJ_TIMECONST 0x0020 /* pll time constant */ | 139 | #define ADJ_TIMECONST 0x0020 /* pll time constant */ |
140 | #define ADJ_TAI 0x0080 /* set TAI offset */ | ||
138 | #define ADJ_MICRO 0x1000 /* select microsecond resolution */ | 141 | #define ADJ_MICRO 0x1000 /* select microsecond resolution */ |
139 | #define ADJ_NANO 0x2000 /* select nanosecond resolution */ | 142 | #define ADJ_NANO 0x2000 /* select nanosecond resolution */ |
140 | #define ADJ_TICK 0x4000 /* tick value */ | 143 | #define ADJ_TICK 0x4000 /* tick value */ |
diff --git a/kernel/compat.c b/kernel/compat.c index 4a856a3643bb..32c254a8ab9a 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -955,7 +955,8 @@ asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp) | |||
955 | __put_user(txc.jitcnt, &utp->jitcnt) || | 955 | __put_user(txc.jitcnt, &utp->jitcnt) || |
956 | __put_user(txc.calcnt, &utp->calcnt) || | 956 | __put_user(txc.calcnt, &utp->calcnt) || |
957 | __put_user(txc.errcnt, &utp->errcnt) || | 957 | __put_user(txc.errcnt, &utp->errcnt) || |
958 | __put_user(txc.stbcnt, &utp->stbcnt)) | 958 | __put_user(txc.stbcnt, &utp->stbcnt) || |
959 | __put_user(txc.tai, &utp->tai)) | ||
959 | ret = -EFAULT; | 960 | ret = -EFAULT; |
960 | 961 | ||
961 | return ret; | 962 | return ret; |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 44491de312a0..10fe17df45a0 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -35,6 +35,7 @@ static u64 tick_length, tick_length_base; | |||
35 | /* TIME_ERROR prevents overwriting the CMOS clock */ | 35 | /* TIME_ERROR prevents overwriting the CMOS clock */ |
36 | static int time_state = TIME_OK; /* clock synchronization status */ | 36 | static int time_state = TIME_OK; /* clock synchronization status */ |
37 | int time_status = STA_UNSYNC; /* clock status bits */ | 37 | int time_status = STA_UNSYNC; /* clock status bits */ |
38 | static long time_tai; /* TAI offset (s) */ | ||
38 | static s64 time_offset; /* time adjustment (ns) */ | 39 | static s64 time_offset; /* time adjustment (ns) */ |
39 | static long time_constant = 2; /* pll time constant */ | 40 | static long time_constant = 2; /* pll time constant */ |
40 | long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ | 41 | long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ |
@@ -162,6 +163,7 @@ void second_overflow(void) | |||
162 | case TIME_DEL: | 163 | case TIME_DEL: |
163 | if ((xtime.tv_sec + 1) % 86400 == 0) { | 164 | if ((xtime.tv_sec + 1) % 86400 == 0) { |
164 | xtime.tv_sec++; | 165 | xtime.tv_sec++; |
166 | time_tai--; | ||
165 | wall_to_monotonic.tv_sec--; | 167 | wall_to_monotonic.tv_sec--; |
166 | time_state = TIME_WAIT; | 168 | time_state = TIME_WAIT; |
167 | printk(KERN_NOTICE "Clock: deleting leap second " | 169 | printk(KERN_NOTICE "Clock: deleting leap second " |
@@ -169,6 +171,7 @@ void second_overflow(void) | |||
169 | } | 171 | } |
170 | break; | 172 | break; |
171 | case TIME_OOP: | 173 | case TIME_OOP: |
174 | time_tai++; | ||
172 | time_state = TIME_WAIT; | 175 | time_state = TIME_WAIT; |
173 | break; | 176 | break; |
174 | case TIME_WAIT: | 177 | case TIME_WAIT: |
@@ -340,6 +343,9 @@ int do_adjtimex(struct timex *txc) | |||
340 | time_constant = max(time_constant, 0l); | 343 | time_constant = max(time_constant, 0l); |
341 | } | 344 | } |
342 | 345 | ||
346 | if (txc->modes & ADJ_TAI && txc->constant > 0) | ||
347 | time_tai = txc->constant; | ||
348 | |||
343 | if (txc->modes & ADJ_OFFSET) { | 349 | if (txc->modes & ADJ_OFFSET) { |
344 | if (txc->modes == ADJ_OFFSET_SINGLESHOT) | 350 | if (txc->modes == ADJ_OFFSET_SINGLESHOT) |
345 | /* adjtime() is independent from ntp_adjtime() */ | 351 | /* adjtime() is independent from ntp_adjtime() */ |
@@ -377,6 +383,7 @@ int do_adjtimex(struct timex *txc) | |||
377 | txc->precision = 1; | 383 | txc->precision = 1; |
378 | txc->tolerance = MAXFREQ_SCALED / PPM_SCALE; | 384 | txc->tolerance = MAXFREQ_SCALED / PPM_SCALE; |
379 | txc->tick = tick_usec; | 385 | txc->tick = tick_usec; |
386 | txc->tai = time_tai; | ||
380 | 387 | ||
381 | /* PPS is not implemented, so these are zero */ | 388 | /* PPS is not implemented, so these are zero */ |
382 | txc->ppsfreq = 0; | 389 | txc->ppsfreq = 0; |