This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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@sgi.com>");
 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]