Index: linus/include/linux/time.h =================================================================== --- linus.orig/include/linux/time.h 2004-10-06 09:52:00.000000000 -0700 +++ linus/include/linux/time.h 2004-10-06 10:16:04.000000000 -0700 @@ -418,7 +418,7 @@ /* * The IDs of various hardware clocks */ - +#define CLOCK_SGI_CYCLE 10 #define MAX_CLOCKS 16 #define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC | \ 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-10-06 10:16:04.000000000 -0700 @@ -28,6 +28,7 @@ #include #include #include +#include MODULE_AUTHOR("Jesse Barnes "); 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);