21 #include <linux/types.h>
22 #include <linux/kernel.h>
24 #include <linux/module.h>
26 #include <linux/errno.h>
33 #include <linux/time.h>
36 #include <linux/slab.h>
38 #include <asm/uaccess.h>
39 #include <asm/sn/addrs.h>
40 #include <asm/sn/intr.h>
50 #define MMTIMER_NAME "mmtimer"
51 #define MMTIMER_DESC "SGI Altix RTC Timer"
52 #define MMTIMER_VERSION "2.1"
56 static struct k_clock sgi_clock;
60 #define RTC_COUNTER_ADDR ((long *)LOCAL_MMR_ADDR(SH_RTC))
62 #define rtc_time() (*RTC_COUNTER_ADDR)
65 static long mmtimer_ioctl(
struct file *
file,
unsigned int cmd,
72 static unsigned long mmtimer_femtoperiod = 0;
77 .unlocked_ioctl = mmtimer_ioctl,
96 static void mmtimer_clr_int_pending(
int comparator)
103 static void mmtimer_setup_int_0(
int cpu,
u64 expires)
114 mmtimer_clr_int_pending(0);
133 static void mmtimer_setup_int_1(
int cpu,
u64 expires)
141 mmtimer_clr_int_pending(1);
155 static void mmtimer_setup_int_2(
int cpu,
u64 expires)
163 mmtimer_clr_int_pending(2);
181 static int mmtimer_setup(
int cpu,
int comparator,
unsigned long expires,
182 u64 *set_completion_time)
184 switch (comparator) {
186 mmtimer_setup_int_0(cpu, expires);
189 mmtimer_setup_int_1(cpu, expires);
192 mmtimer_setup_int_2(cpu, expires);
197 if (*set_completion_time <= expires)
204 return mmtimer_int_pending(comparator);
207 static int mmtimer_disable_int(
long nasid,
int comparator)
209 switch (comparator) {
230 #define TIMER_OFF 0xbadcabLL
233 #define MMTIMER_INTERVAL_RETRY_INCREMENT_DEFAULT 40
250 static unsigned mmtimer_interval_retry_increment =
254 "RTC ticks to add to expiration on interval retry (default 40)");
260 static void mmtimer_add_list(
struct mmtimer *
n)
262 int nodeid = n->
timer->it.mmtimer.node;
263 unsigned long expires = n->
timer->it.mmtimer.expires;
275 if (expires < x->
timer->it.mmtimer.expires)
285 rb_link_node(&n->
list, parent, link);
297 static void mmtimer_set_next_timer(
int nodeid)
315 &set_completion_time)) {
326 &set_completion_time)) {
330 expires = set_completion_time +
331 mmtimer_interval_retry_increment + (1 <<
i);
377 static long mmtimer_ioctl(
struct file *
file,
unsigned int cmd,
397 &mmtimer_femtoperiod,
sizeof(
unsigned long)))
404 sizeof(
unsigned long)))
437 static int mmtimer_mmap(
struct file *file,
struct vm_area_struct *vma)
439 unsigned long mmtimer_addr;
454 mmtimer_addr &= 0xfffffffffffffff
UL;
471 static struct timespec sgi_clock_offset;
472 static int sgi_clock_period;
478 static struct timespec sgi_clock_offset;
479 static int sgi_clock_period;
485 nsec =
rtc_time() * sgi_clock_period
486 + sgi_clock_offset.tv_nsec;
488 tp->
tv_sec += sgi_clock_offset.tv_sec;
498 nsec =
rtc_time() * sgi_clock_period;
503 sgi_clock_offset.tv_nsec = tp->
tv_sec - rem;
506 sgi_clock_offset.tv_sec--;
525 mmtimer_interrupt(
int irq,
void *
dev_id)
527 unsigned long expires = 0;
532 spin_lock(&timers[indx].lock);
535 spin_unlock(&timers[indx].lock);
541 expires = base->
timer->it.mmtimer.expires;
544 (expires && (expires <=
rtc_time()))) {
546 tasklet_schedule(&timers[indx].
tasklet);
550 spin_unlock(&timers[indx].lock);
554 static void mmtimer_tasklet(
unsigned long data)
591 mmtimer_set_next_timer(nodeid);
595 spin_unlock_irqrestore(&mn->lock, flags);
610 static int sgi_timer_del(
struct k_itimer *timr)
613 unsigned long irqflags;
617 unsigned long expires = timr->
it.
mmtimer.expires;
627 if (t->
timer == timr)
630 if (expires < t->
timer->it.mmtimer.expires)
637 spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
641 if (timers[nodeid].
next == n) {
646 rb_erase(n, &timers[nodeid].timer_head);
652 mmtimer_set_next_timer(nodeid);
655 spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
676 static int sgi_timer_set(
struct k_itimer *timr,
int flags,
680 unsigned long when,
period, irqflags;
687 sgi_timer_get(timr, old_setting);
690 when = timespec_to_ns(&new_setting->
it_value);
691 period = timespec_to_ns(&new_setting->
it_interval);
706 now = timespec_to_ns(&n);
719 when = (when + sgi_clock_period - 1) / sgi_clock_period +
rtc_time();
720 period = (period + sgi_clock_period - 1) / sgi_clock_period;
742 n = timers[nodeid].
next;
745 mmtimer_add_list(base);
747 if (timers[nodeid].
next == n) {
749 spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
758 mmtimer_set_next_timer(nodeid);
761 spin_unlock_irqrestore(&timers[nodeid].lock, irqflags);
771 tp->
tv_nsec = sgi_clock_period;
775 static struct k_clock sgi_clock = {
776 .clock_set = sgi_clock_set,
777 .clock_get = sgi_clock_get,
778 .clock_getres = sgi_clock_getres,
779 .timer_create = sgi_timer_create,
780 .timer_set = sgi_timer_set,
781 .timer_del = sgi_timer_del,
782 .timer_get = sgi_timer_get
790 static int __init mmtimer_init(
void)
800 if (sn_rtc_cycles_per_second < 100000) {
806 mmtimer_femtoperiod = ((
unsigned long)1E15 + sn_rtc_cycles_per_second /
839 (
unsigned long) node);
846 sn_rtc_cycles_per_second/(
unsigned long)1E6);