Index: linus/include/linux/mmtimer.h
===================================================================
--- linus.orig/include/linux/mmtimer.h	2004-09-27 12:19:27.000000000 -0700
+++ linus/include/linux/mmtimer.h	2004-09-30 13:11:43.000000000 -0700
@@ -53,4 +53,5 @@
 #define MMTIMER_MMAPAVAIL _IO(MMTIMER_IOCTL_BASE, 6)
 #define MMTIMER_GETCOUNTER _IOR(MMTIMER_IOCTL_BASE, 9, unsigned long)
 
+#define CLOCK_SGI_CYCLE 10
 #endif /* _LINUX_MMTIMER_H */
Index: linus/include/linux/time.h
===================================================================
--- linus.orig/include/linux/time.h	2004-09-30 13:07:33.000000000 -0700
+++ linus/include/linux/time.h	2004-09-30 13:11:31.000000000 -0700
@@ -415,7 +415,7 @@
 #define CLOCK_REALTIME_HR	 4
 #define CLOCK_MONOTONIC_HR	  5
 
-#define MAX_CLOCKS 6
+#define MAX_CLOCKS 16
 #define CLOCKS_MASK  (CLOCK_REALTIME | CLOCK_MONOTONIC | \
                      CLOCK_REALTIME_HR | CLOCK_MONOTONIC_HR)
 #define CLOCKS_MONO (CLOCK_MONOTONIC & CLOCK_MONOTONIC_HR)
Index: linus/drivers/char/mmtimer.c
===================================================================
--- linus.orig/drivers/char/mmtimer.c	2004-09-27 12:19:27.000000000 -0700
+++ linus/drivers/char/mmtimer.c	2004-09-30 13:45:54.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,44 @@
 	&mmtimer_fops
 };
 
+struct timespec sgi_clock_offset;
+
+int sgi_clock_get(struct timespec *tp) {
+	u64 nsec;
+
+	nsec = *(u64 *) RTC_COUNTER_ADDR * sn_rtc_cycles_per_second
+			+ 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;
+};
+
+int sgi_clock_set(struct timespec *tp) {
+	
+	u64 nsec;
+	u64 rem;
+
+	nsec = *(u64 *)RTC_COUNTER_ADDR * sn_rtc_cycles_per_second;
+	
+	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 +245,9 @@
 		return -1;
 	}
 
+	sgi_clock.res = 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);