Re: Posix compliant cpu clocks V6 [3/3]: mmtimer provides CLOCK_SGI_CYCLE

From: Christoph Lameter
Date: Fri Oct 01 2004 - 15:14:56 EST


Changelog:
* Add CLOCK_SGI_CYCLE provided by drivers/char/mmtimer

Index: linux-2.6.9-rc3/include/linux/time.h
===================================================================
--- linux-2.6.9-rc3.orig/include/linux/time.h 2004-10-01 08:40:30.000000000 -0700
+++ linux-2.6.9-rc3/include/linux/time.h 2004-10-01 09:09:28.000000000 -0700
@@ -416,7 +416,7 @@
/*
* The IDs of various hardware clocks
*/
-
+#define CLOCK_SGI_CYCLE 10

#define MAX_CLOCKS 16
#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC | \
Index: linux-2.6.9-rc3/drivers/char/mmtimer.c
===================================================================
--- linux-2.6.9-rc3.orig/drivers/char/mmtimer.c 2004-09-29 20:05:19.000000000 -0700
+++ linux-2.6.9-rc3/drivers/char/mmtimer.c 2004-10-01 10:07:11.000000000 -0700
@@ -28,6 +28,7 @@
#include <asm/uaccess.h>
#include <asm/sn/addrs.h>
#include <asm/sn/clksupport.h>
+#include <linux/posix-timers.h>

MODULE_AUTHOR("Jesse Barnes <jbarnes@xxxxxxx>");
MODULE_DESCRIPTION("Multimedia timer support");
@@ -177,6 +178,45 @@
&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
*
@@ -206,6 +246,9 @@
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,
sn_rtc_cycles_per_second/(unsigned long)1E6);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/