uml: tickless support
[linux-2.6.git] / arch / um / kernel / time.c
index 3cb7135..2acdc7e 100644 (file)
@@ -20,41 +20,12 @@ unsigned long long sched_clock(void)
        return (unsigned long long)jiffies_64 * (1000000000 / HZ);
 }
 
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
-static unsigned long long prev_nsecs[NR_CPUS];
-static long long delta[NR_CPUS];               /* Deviation per interval */
-#endif
-
 void timer_handler(int sig, struct uml_pt_regs *regs)
 {
-       unsigned long long ticks = 0;
        unsigned long flags;
-#ifdef CONFIG_UML_REAL_TIME_CLOCK
-       int c = cpu();
-       if (prev_nsecs[c]) {
-               /* We've had 1 tick */
-               unsigned long long nsecs = os_nsecs();
-
-               delta[c] += nsecs - prev_nsecs[c];
-               prev_nsecs[c] = nsecs;
-
-               /* Protect against the host clock being set backwards */
-               if (delta[c] < 0)
-                       delta[c] = 0;
-
-               ticks += (delta[c] * HZ) / BILLION;
-               delta[c] -= (ticks * BILLION) / HZ;
-       }
-       else prev_nsecs[c] = os_nsecs();
-#else
-       ticks = 1;
-#endif
 
        local_irq_save(flags);
-       while (ticks > 0) {
-               do_IRQ(TIMER_IRQ, regs);
-               ticks--;
-       }
+       do_IRQ(TIMER_IRQ, regs);
        local_irq_restore(flags);
 }
 
@@ -68,10 +39,8 @@ static void itimer_set_mode(enum clock_event_mode mode,
 
        case CLOCK_EVT_MODE_SHUTDOWN:
        case CLOCK_EVT_MODE_UNUSED:
-               disable_timer();
-               break;
        case CLOCK_EVT_MODE_ONESHOT:
-               BUG();
+               disable_timer();
                break;
 
        case CLOCK_EVT_MODE_RESUME:
@@ -79,13 +48,19 @@ static void itimer_set_mode(enum clock_event_mode mode,
        }
 }
 
+static int itimer_next_event(unsigned long delta,
+                            struct clock_event_device *evt)
+{
+       return timer_one_shot(delta + 1);
+}
+
 static struct clock_event_device itimer_clockevent = {
        .name           = "itimer",
        .rating         = 250,
        .cpumask        = CPU_MASK_ALL,
-       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
        .set_mode       = itimer_set_mode,
-       .set_next_event = NULL,
+       .set_next_event = itimer_next_event,
        .shift          = 32,
        .irq            = 0,
 };