Commit 6d338e92 authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

[PATCH] Posix compliant cpu clocks V6: mmtimer provides CLOCK_SGI_CYCLE

* Add CLOCK_SGI_CYCLE provided by drivers/char/mmtimer
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bb82e8a5
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#include <linux/mmtimer.h> #include <linux/mmtimer.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/posix-timers.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/sn/addrs.h> #include <asm/sn/addrs.h>
#include <asm/sn/clksupport.h> #include <asm/sn/clksupport.h>
...@@ -178,6 +180,45 @@ static struct miscdevice mmtimer_miscdev = { ...@@ -178,6 +180,45 @@ static struct miscdevice mmtimer_miscdev = {
&mmtimer_fops &mmtimer_fops
}; };
static struct timespec sgi_clock_offset;
static int sgi_clock_period;
static int sgi_clock_get(struct timespec *tp) {
u64 nsec;
nsec = readq(RTC_COUNTER_ADDR) * sgi_clock_period
+ sgi_clock_offset.tv_nsec;
tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec)
+ sgi_clock_offset.tv_sec;
return 0;
};
static int sgi_clock_set(struct timespec *tp) {
u64 nsec;
u64 rem;
nsec = readq(RTC_COUNTER_ADDR) * sgi_clock_period;
sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem);
if (rem <= tp->tv_nsec)
sgi_clock_offset.tv_nsec = tp->tv_sec - rem;
else {
sgi_clock_offset.tv_nsec = tp->tv_sec + NSEC_PER_SEC - rem;
sgi_clock_offset.tv_sec--;
}
return 0;
}
static struct k_clock sgi_clock = {
.res = 0,
.clock_set = sgi_clock_set,
.clock_get = sgi_clock_get,
.timer_create = do_posix_clock_notimer_create,
.nsleep = do_posix_clock_nonanosleep
};
/** /**
* mmtimer_init - device initialization routine * mmtimer_init - device initialization routine
* *
...@@ -207,6 +248,9 @@ static int __init mmtimer_init(void) ...@@ -207,6 +248,9 @@ static int __init mmtimer_init(void)
return -1; return -1;
} }
sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second;
register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock);
printk(KERN_INFO "%s: v%s, %ld MHz\n", MMTIMER_DESC, MMTIMER_VERSION, printk(KERN_INFO "%s: v%s, %ld MHz\n", MMTIMER_DESC, MMTIMER_VERSION,
sn_rtc_cycles_per_second/(unsigned long)1E6); sn_rtc_cycles_per_second/(unsigned long)1E6);
......
...@@ -162,6 +162,7 @@ struct itimerval { ...@@ -162,6 +162,7 @@ struct itimerval {
*/ */
#define CLOCK_SGI_CYCLE 10
#define MAX_CLOCKS 16 #define MAX_CLOCKS 16
#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC | \ #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC | \
CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR) CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment