diff options
author | Richard Cochran <richardcochran@gmail.com> | 2011-02-01 08:52:26 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-02-02 09:28:19 -0500 |
commit | f1f1d5ebd10ffa4242bce7a90a56a222d6b7bc77 (patch) | |
tree | ca04ea979512e0037c52bca855dbf050b1b08360 /kernel/posix-timers.c | |
parent | 65f5d80bdf83ec0d7f3887db10153bf3f36ed73c (diff) |
posix-timers: Introduce a syscall for clock tuning.
A new syscall is introduced that allows tuning of a POSIX clock. The
new call, clock_adjtime, takes two parameters, the clock ID and a
pointer to a struct timex. Any ADJTIMEX(2) operation may be requested
via this system call, but various POSIX clocks may or may not support
tuning.
[ tglx: Adapted to the posix-timer cleanup series. Avoid copy_to_user
in the error case ]
Signed-off-by: Richard Cochran <richard.cochran@omicron.at>
Acked-by: John Stultz <johnstul@us.ibm.com>
LKML-Reference: <20110201134419.869804645@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/posix-timers.c')
-rw-r--r-- | kernel/posix-timers.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index a3fdfd4be0ec..5a5a4f1c0971 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
@@ -170,6 +170,12 @@ static int posix_clock_realtime_set(const clockid_t which_clock, | |||
170 | return do_sys_settimeofday(tp, NULL); | 170 | return do_sys_settimeofday(tp, NULL); |
171 | } | 171 | } |
172 | 172 | ||
173 | static int posix_clock_realtime_adj(const clockid_t which_clock, | ||
174 | struct timex *t) | ||
175 | { | ||
176 | return do_adjtimex(t); | ||
177 | } | ||
178 | |||
173 | /* | 179 | /* |
174 | * Get monotonic time for posix timers | 180 | * Get monotonic time for posix timers |
175 | */ | 181 | */ |
@@ -216,6 +222,7 @@ static __init int init_posix_timers(void) | |||
216 | .clock_getres = hrtimer_get_res, | 222 | .clock_getres = hrtimer_get_res, |
217 | .clock_get = posix_clock_realtime_get, | 223 | .clock_get = posix_clock_realtime_get, |
218 | .clock_set = posix_clock_realtime_set, | 224 | .clock_set = posix_clock_realtime_set, |
225 | .clock_adj = posix_clock_realtime_adj, | ||
219 | .nsleep = common_nsleep, | 226 | .nsleep = common_nsleep, |
220 | .nsleep_restart = hrtimer_nanosleep_restart, | 227 | .nsleep_restart = hrtimer_nanosleep_restart, |
221 | .timer_create = common_timer_create, | 228 | .timer_create = common_timer_create, |
@@ -948,6 +955,29 @@ SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, | |||
948 | return error; | 955 | return error; |
949 | } | 956 | } |
950 | 957 | ||
958 | SYSCALL_DEFINE2(clock_adjtime, const clockid_t, which_clock, | ||
959 | struct timex __user *, utx) | ||
960 | { | ||
961 | struct k_clock *kc = clockid_to_kclock(which_clock); | ||
962 | struct timex ktx; | ||
963 | int err; | ||
964 | |||
965 | if (!kc) | ||
966 | return -EINVAL; | ||
967 | if (!kc->clock_adj) | ||
968 | return -EOPNOTSUPP; | ||
969 | |||
970 | if (copy_from_user(&ktx, utx, sizeof(ktx))) | ||
971 | return -EFAULT; | ||
972 | |||
973 | err = kc->clock_adj(which_clock, &ktx); | ||
974 | |||
975 | if (!err && copy_to_user(utx, &ktx, sizeof(ktx))) | ||
976 | return -EFAULT; | ||
977 | |||
978 | return err; | ||
979 | } | ||
980 | |||
951 | SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, | 981 | SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, |
952 | struct timespec __user *, tp) | 982 | struct timespec __user *, tp) |
953 | { | 983 | { |