*
* Called from power state control code with interrupts disabled
*/
- -ktime_t tick_nohz_get_sleep_length(void)
+ +ktime_t tick_nohz_get_sleep_length(ktime_t *delta_next)
{
+ + struct clock_event_device *dev = __this_cpu_read(tick_cpu_device.evtdev);
struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
- return ts->sleep_length;
+ + int cpu = smp_processor_id();
+ + /*
+ + * The idle entry time is expected to be a sufficient approximation of
+ + * the current time at this point.
+ + */
+ + ktime_t now = ts->idle_entrytime;
+ + ktime_t next_event;
+ +
+ + WARN_ON_ONCE(!ts->inidle);
+ +
+ + *delta_next = ktime_sub(dev->next_event, now);
+
- return ts->sleep_length;
+ + if (!can_stop_idle_tick(cpu, ts))
+ + return *delta_next;
+ +
+ + next_event = tick_nohz_next_event(ts, cpu);
+ + if (!next_event)
+ + return *delta_next;
+ +
+ + /*
+ + * If the next highres timer to expire is earlier than next_event, the
+ + * idle governor needs to know that.
+ + */
+ + next_event = min_t(u64, next_event,
+ + hrtimer_next_event_without(&ts->sched_timer));
+
+ + return ktime_sub(next_event, now);
}
/**