These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / kernel / time / tick-oneshot.c
index 67a64b1..b513446 100644 (file)
@@ -28,6 +28,22 @@ int tick_program_event(ktime_t expires, int force)
 {
        struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
 
+       if (unlikely(expires.tv64 == KTIME_MAX)) {
+               /*
+                * We don't need the clock event device any more, stop it.
+                */
+               clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT_STOPPED);
+               return 0;
+       }
+
+       if (unlikely(clockevent_state_oneshot_stopped(dev))) {
+               /*
+                * We need the clock event again, configure it in ONESHOT mode
+                * before using it.
+                */
+               clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
+       }
+
        return clockevents_program_event(dev, expires, force);
 }
 
@@ -38,7 +54,7 @@ void tick_resume_oneshot(void)
 {
        struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
 
-       clockevents_set_state(dev, CLOCK_EVT_STATE_ONESHOT);
+       clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
        clockevents_program_event(dev, ktime_get(), true);
 }
 
@@ -50,7 +66,7 @@ void tick_setup_oneshot(struct clock_event_device *newdev,
                        ktime_t next_event)
 {
        newdev->event_handler = handler;
-       clockevents_set_state(newdev, CLOCK_EVT_STATE_ONESHOT);
+       clockevents_switch_state(newdev, CLOCK_EVT_STATE_ONESHOT);
        clockevents_program_event(newdev, next_event, true);
 }
 
@@ -81,7 +97,7 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
 
        td->mode = TICKDEV_MODE_ONESHOT;
        dev->event_handler = handler;
-       clockevents_set_state(dev, CLOCK_EVT_STATE_ONESHOT);
+       clockevents_switch_state(dev, CLOCK_EVT_STATE_ONESHOT);
        tick_broadcast_switch_to_oneshot();
        return 0;
 }