.ioctl = mmtimer_ioctl,
};
-/*
- * Comparators and their associated info. Shub has
- * three comparison registers.
- */
-
/*
* We only have comparison registers RTC1-4 currently available per
* node. RTC0 is used by SAL.
* This function must be called with interrupts disabled and preemption off
* in order to insure that the setup succeeds in a deterministic time frame.
* It will check if the interrupt setup succeeded.
- * mmtimer_setup will return the cycles that we were too late if the
- * initialization failed.
*/
static int inline mmtimer_setup(int comparator, unsigned long expires)
{
- long diff;
-
switch (comparator) {
case 0:
mmtimer_setup_int_0(expires);
break;
}
/* We might've missed our expiration time */
- diff = rtc_time() - expires;
- if (diff > 0) {
- if (mmtimer_int_pending(comparator)) {
- /* We'll get an interrupt for this once we're done */
- return 0;
- }
- /* Looks like we missed it */
- return diff;
- }
+ if (rtc_time() < expires)
+ return 1;
- return 0;
+ /*
+ * If an interrupt is already pending then its okay
+ * if not then we failed
+ */
+ return mmtimer_int_pending(comparator);
}
static int inline mmtimer_disable_int(long nasid, int comparator)
static struct timespec sgi_clock_offset;
static int sgi_clock_period;
-static int sgi_clock_get(struct timespec *tp)
+static int sgi_clock_get(clockid_t clockid, struct timespec *tp)
{
u64 nsec;
return 0;
};
-static int sgi_clock_set(struct timespec *tp)
+static int sgi_clock_set(clockid_t clockid, struct timespec *tp)
{
u64 nsec;
int n;
struct k_itimer *t = x->timer;
- t->it_timer.magic = x->i;
+ t->it.mmtimer.clock = x->i;
t->it_overrun--;
n = 0;
do {
- t->it_timer.expires += t->it_incr << n;
+ t->it.mmtimer.expires += t->it.mmtimer.incr << n;
t->it_overrun += 1 << n;
n++;
if (n > 20)
return 1;
- } while (mmtimer_setup(x->i, t->it_timer.expires));
+ } while (!mmtimer_setup(x->i, t->it.mmtimer.expires));
return 0;
}
spin_lock(&base[i].lock);
if (base[i].cpu == smp_processor_id()) {
if (base[i].timer)
- expires = base[i].timer->it_timer.expires;
+ expires = base[i].timer->it.mmtimer.expires;
/* expires test won't work with shared irqs */
if ((mmtimer_int_pending(i) > 0) ||
(expires && (expires < rtc_time()))) {
goto out;
t->it_overrun = 0;
- if (tasklist_lock.write_lock || posix_timer_event(t, 0) != 0) {
+ if (posix_timer_event(t, 0) != 0) {
// printk(KERN_WARNING "mmtimer: cannot deliver signal.\n");
t->it_overrun++;
}
- if(t->it_incr) {
+ if(t->it.mmtimer.incr) {
/* Periodic timer */
if (reschedule_periodic_timer(x)) {
printk(KERN_WARNING "mmtimer: unable to reschedule\n");
}
} else {
/* Ensure we don't false trigger in mmtimer_interrupt */
- t->it_timer.expires = 0;
+ t->it.mmtimer.expires = 0;
}
t->it_overrun_last = t->it_overrun;
out:
static int sgi_timer_create(struct k_itimer *timer)
{
/* Insure that a newly created timer is off */
- timer->it_timer.magic = TIMER_OFF;
+ timer->it.mmtimer.clock = TIMER_OFF;
return 0;
}
*/
static int sgi_timer_del(struct k_itimer *timr)
{
- int i = timr->it_timer.magic;
- cnodeid_t nodeid = timr->it_timer.data;
+ int i = timr->it.mmtimer.clock;
+ cnodeid_t nodeid = timr->it.mmtimer.node;
mmtimer_t *t = timers + nodeid * NUM_COMPARATORS +i;
unsigned long irqflags;
spin_lock_irqsave(&t->lock, irqflags);
mmtimer_disable_int(cnodeid_to_nasid(nodeid),i);
t->timer = NULL;
- timr->it_timer.magic = TIMER_OFF;
- timr->it_timer.expires = 0;
+ timr->it.mmtimer.clock = TIMER_OFF;
+ timr->it.mmtimer.expires = 0;
spin_unlock_irqrestore(&t->lock, irqflags);
}
return 0;
static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
{
- if (timr->it_timer.magic == TIMER_OFF) {
+ if (timr->it.mmtimer.clock == TIMER_OFF) {
cur_setting->it_interval.tv_nsec = 0;
cur_setting->it_interval.tv_sec = 0;
cur_setting->it_value.tv_nsec = 0;
return;
}
- ns_to_timespec(cur_setting->it_interval, timr->it_incr * sgi_clock_period);
- ns_to_timespec(cur_setting->it_value, (timr->it_timer.expires - rtc_time())* sgi_clock_period);
+ ns_to_timespec(cur_setting->it_interval, timr->it.mmtimer.incr * sgi_clock_period);
+ ns_to_timespec(cur_setting->it_value, (timr->it.mmtimer.expires - rtc_time())* sgi_clock_period);
return;
}
if (flags & TIMER_ABSTIME) {
struct timespec n;
+ unsigned long now;
getnstimeofday(&n);
- when -= timespec_to_ns(n);
+ now = timespec_to_ns(n);
+ if (when > now)
+ when -= now;
+ else
+ /* Fire the timer immediately */
+ when = 0;
}
/*
base[i].timer = timr;
base[i].cpu = smp_processor_id();
- timr->it_timer.magic = i;
- timr->it_timer.data = nodeid;
- timr->it_incr = period;
- timr->it_timer.expires = when;
+ timr->it.mmtimer.clock = i;
+ timr->it.mmtimer.node = nodeid;
+ timr->it.mmtimer.incr = period;
+ timr->it.mmtimer.expires = when;
if (period == 0) {
- if (mmtimer_setup(i, when)) {
+ if (!mmtimer_setup(i, when)) {
mmtimer_disable_int(-1, i);
posix_timer_event(timr, 0);
- timr->it_timer.expires = 0;
+ timr->it.mmtimer.expires = 0;
}
} else {
- timr->it_timer.expires -= period;
+ timr->it.mmtimer.expires -= period;
if (reschedule_periodic_timer(base+i))
err = -EINVAL;
}