/* Returns 0 on success, -ETIME when the event is in the past.  */
int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, ktime_t now)
/* Returns 0 on success, -ETIME when the event is in the past.  */
int clockevents_program_event(struct clock_event_device *dev, ktime_t expires, ktime_t now)
{
	unsigned long long clc;
	int64_t delta;
	if (unlikely(expires.tv64 < 0)) {
		WARN_ON_ONCE(1);
		return -ETIME;
	}
	delta = ktime_to_ns(ktime_sub(expires, now));
	if (delta <= 0 || !dev->set_next_event)
		return -ETIME;
	dev->next_event = expires;
	if (dev->mode == CLOCK_EVT_MODE_SHUTDOWN)
		return 0;
	if (delta > dev->max_delta_ns) {
		delta = dev->max_delta_ns;
	}
	if (delta < dev->min_delta_ns)
		delta = dev->min_delta_ns;
	clc = delta * dev->mult;
	clc >>= dev->shift;
	return dev->set_next_event((unsigned long) clc, dev);
}