Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe31fca3 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

Merge tag 'fortglx-3.20-time' of https://git.linaro.org/people/john.stultz/linux into timers/core

Pull time updates from John Stultz for 3.20:

 * ktime division optimization
 * Expose a few more y2038-safe timekeeping interfaces
 * RTC core changes to address y2038
parents 9bc74919 9a4a445e
Loading
Loading
Loading
Loading
+5 −13
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ static int __init rtc_hctosys(void)
{
	int err = -ENODEV;
	struct rtc_time tm;
	struct timespec tv = {
	struct timespec64 tv64 = {
		.tv_nsec = NSEC_PER_SEC >> 1,
	};
	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
@@ -45,25 +45,17 @@ static int __init rtc_hctosys(void)

	}

	err = rtc_valid_tm(&tm);
	if (err) {
		dev_err(rtc->dev.parent,
			"hctosys: invalid date/time\n");
		goto err_invalid;
	}

	rtc_tm_to_time(&tm, &tv.tv_sec);
	tv64.tv_sec = rtc_tm_to_time64(&tm);

	err = do_settimeofday(&tv);
	err = do_settimeofday64(&tv64);

	dev_info(rtc->dev.parent,
		"setting system clock to "
		"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
		"%d-%02d-%02d %02d:%02d:%02d UTC (%lld)\n",
		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
		tm.tm_hour, tm.tm_min, tm.tm_sec,
		(unsigned int) tv.tv_sec);
		(long long) tv64.tv_sec);

err_invalid:
err_read:
	rtc_class_close(rtc);

+10 −12
Original line number Diff line number Diff line
@@ -73,10 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
	else if (rtc->ops->set_time)
		err = rtc->ops->set_time(rtc->dev.parent, tm);
	else if (rtc->ops->set_mmss) {
		unsigned long secs;
		err = rtc_tm_to_time(tm, &secs);
		if (err == 0)
			err = rtc->ops->set_mmss(rtc->dev.parent, secs);
		time64_t secs64 = rtc_tm_to_time64(tm);
		err = rtc->ops->set_mmss(rtc->dev.parent, secs64);
	} else
		err = -EINVAL;

@@ -105,7 +103,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)

		err = rtc->ops->read_time(rtc->dev.parent, &old);
		if (err == 0) {
			rtc_time_to_tm(secs, &new);
			rtc_time64_to_tm(secs, &new);

			/*
			 * avoid writing when we're going to change the day of
@@ -157,7 +155,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
	int err;
	struct rtc_time before, now;
	int first_time = 1;
	unsigned long t_now, t_alm;
	time64_t t_now, t_alm;
	enum { none, day, month, year } missing = none;
	unsigned days;

@@ -258,8 +256,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
	}

	/* with luck, no rollover is needed */
	rtc_tm_to_time(&now, &t_now);
	rtc_tm_to_time(&alarm->time, &t_alm);
	t_now = rtc_tm_to_time64(&now);
	t_alm = rtc_tm_to_time64(&alarm->time);
	if (t_now < t_alm)
		goto done;

@@ -273,7 +271,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
	case day:
		dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day");
		t_alm += 24 * 60 * 60;
		rtc_time_to_tm(t_alm, &alarm->time);
		rtc_time64_to_tm(t_alm, &alarm->time);
		break;

	/* Month rollover ... if it's the 31th, an alarm on the 3rd will
@@ -346,19 +344,19 @@ EXPORT_SYMBOL_GPL(rtc_read_alarm);
static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
	struct rtc_time tm;
	long now, scheduled;
	time64_t now, scheduled;
	int err;

	err = rtc_valid_tm(&alarm->time);
	if (err)
		return err;
	rtc_tm_to_time(&alarm->time, &scheduled);
	scheduled = rtc_tm_to_time64(&alarm->time);

	/* Make sure we're not setting alarms in the past */
	err = __rtc_read_time(rtc, &tm);
	if (err)
		return err;
	rtc_tm_to_time(&tm, &now);
	now = rtc_tm_to_time64(&tm);
	if (scheduled <= now)
		return -ETIME;
	/*
+4 −4
Original line number Diff line number Diff line
@@ -304,12 +304,12 @@ static long rtc_dev_ioctl(struct file *file,
		 * Not supported here.
		 */
		{
			unsigned long now, then;
			time64_t now, then;

			err = rtc_read_time(rtc, &tm);
			if (err < 0)
				return err;
			rtc_tm_to_time(&tm, &now);
			now = rtc_tm_to_time64(&tm);

			alarm.time.tm_mday = tm.tm_mday;
			alarm.time.tm_mon = tm.tm_mon;
@@ -317,11 +317,11 @@ static long rtc_dev_ioctl(struct file *file,
			err  = rtc_valid_tm(&alarm.time);
			if (err < 0)
				return err;
			rtc_tm_to_time(&alarm.time, &then);
			then = rtc_tm_to_time64(&alarm.time);

			/* alarm may need to wrap into tomorrow */
			if (then < now) {
				rtc_time_to_tm(now + 24 * 60 * 60, &tm);
				rtc_time64_to_tm(now + 24 * 60 * 60, &tm);
				alarm.time.tm_mday = tm.tm_mday;
				alarm.time.tm_mon = tm.tm_mon;
				alarm.time.tm_year = tm.tm_year;
+3 −3
Original line number Diff line number Diff line
@@ -20,16 +20,16 @@
 *
 * If temporary failure is indicated the caller should try again 'soon'
 */
int rtc_set_ntp_time(struct timespec now)
int rtc_set_ntp_time(struct timespec64 now)
{
	struct rtc_device *rtc;
	struct rtc_time tm;
	int err = -ENODEV;

	if (now.tv_nsec < (NSEC_PER_SEC >> 1))
		rtc_time_to_tm(now.tv_sec, &tm);
		rtc_time64_to_tm(now.tv_sec, &tm);
	else
		rtc_time_to_tm(now.tv_sec + 1, &tm);
		rtc_time64_to_tm(now.tv_sec + 1, &tm);

	rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
	if (rtc) {
+11 −1
Original line number Diff line number Diff line
@@ -166,7 +166,17 @@ static inline bool ktime_before(const ktime_t cmp1, const ktime_t cmp2)
}

#if BITS_PER_LONG < 64
extern u64 ktime_divns(const ktime_t kt, s64 div);
extern u64 __ktime_divns(const ktime_t kt, s64 div);
static inline u64 ktime_divns(const ktime_t kt, s64 div)
{
	if (__builtin_constant_p(div) && !(div >> 32)) {
		u64 ns = kt.tv64;
		do_div(ns, div);
		return ns;
	} else {
		return __ktime_divns(kt, div);
	}
}
#else /* BITS_PER_LONG < 64 */
# define ktime_divns(kt, div)		(u64)((kt).tv64 / (div))
#endif
Loading