forked from luck/tmp_suning_uos_patched
Couple of items for 3.20
* ktime division optimization * Expose a few more y2038-safe timekeeping interfaces * RTC core changes to address y2038 Signed-off-by: John Stultz <john.stultz@linaro.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJUwvXJAAoJEK8vClot3jMxTAoH/1DMT3fuVx6RFjKJ/P1abIB+ +w3cfEgEWgkSwYmuS0XHq1WppnQ0p0n1GOJcWUPiP9tTGrKcTdp5uG5qMprcga3q XoeR8wefkyEKyH4ukStdGKQKot2Vj117TauDtVNPf2eOOBS5pqOw1dYUlwjlMtOj 45poW5ORNKmBMn90e22k8nlNSI9PebvMh9w6nzeYJWEibdyk96z2TOk1puPTvws/ ppyNzlhnKckpNb49JVxE8B4DNRpXsUV+aUxRNyRPN4OdqCGzHwIJCyEKi6+nbRyb 4HMUhfl8eRB2Iu7zHF2a2XEOqJdOjl8i1DsTwr3Vwd3crf4XkXD6WtTtGl2YKkU= =YhDu -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
fe31fca35d
|
@ -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;
|
||||
}
|
||||
tv64.tv_sec = rtc_tm_to_time64(&tm);
|
||||
|
||||
rtc_tm_to_time(&tm, &tv.tv_sec);
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -161,7 +161,7 @@ extern void devm_rtc_device_unregister(struct device *dev,
|
|||
extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
|
||||
extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
|
||||
extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs);
|
||||
extern int rtc_set_ntp_time(struct timespec now);
|
||||
extern int rtc_set_ntp_time(struct timespec64 now);
|
||||
int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
|
||||
extern int rtc_read_alarm(struct rtc_device *rtc,
|
||||
struct rtc_wkalrm *alrm);
|
||||
|
|
|
@ -33,6 +33,7 @@ extern time64_t ktime_get_real_seconds(void);
|
|||
|
||||
extern int __getnstimeofday64(struct timespec64 *tv);
|
||||
extern void getnstimeofday64(struct timespec64 *tv);
|
||||
extern void getboottime64(struct timespec64 *ts);
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
/**
|
||||
|
@ -72,6 +73,11 @@ static inline struct timespec get_monotonic_coarse(void)
|
|||
{
|
||||
return get_monotonic_coarse64();
|
||||
}
|
||||
|
||||
static inline void getboottime(struct timespec *ts)
|
||||
{
|
||||
return getboottime64(ts);
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Deprecated. Use do_settimeofday64().
|
||||
|
@ -129,9 +135,15 @@ static inline struct timespec get_monotonic_coarse(void)
|
|||
{
|
||||
return timespec64_to_timespec(get_monotonic_coarse64());
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void getboottime(struct timespec *ts);
|
||||
static inline void getboottime(struct timespec *ts)
|
||||
{
|
||||
struct timespec64 ts64;
|
||||
|
||||
getboottime64(&ts64);
|
||||
*ts = timespec64_to_timespec(ts64);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
|
||||
#define ktime_get_real_ts64(ts) getnstimeofday64(ts)
|
||||
|
@ -217,6 +229,11 @@ static inline void get_monotonic_boottime(struct timespec *ts)
|
|||
*ts = ktime_to_timespec(ktime_get_boottime());
|
||||
}
|
||||
|
||||
static inline void get_monotonic_boottime64(struct timespec64 *ts)
|
||||
{
|
||||
*ts = ktime_to_timespec64(ktime_get_boottime());
|
||||
}
|
||||
|
||||
static inline void timekeeping_clocktai(struct timespec *ts)
|
||||
{
|
||||
*ts = ktime_to_timespec(ktime_get_clocktai());
|
||||
|
|
|
@ -266,7 +266,7 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
|
|||
/*
|
||||
* Divide a ktime value by a nanosecond value
|
||||
*/
|
||||
u64 ktime_divns(const ktime_t kt, s64 div)
|
||||
u64 __ktime_divns(const ktime_t kt, s64 div)
|
||||
{
|
||||
u64 dclc;
|
||||
int sft = 0;
|
||||
|
@ -282,7 +282,7 @@ u64 ktime_divns(const ktime_t kt, s64 div)
|
|||
|
||||
return dclc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ktime_divns);
|
||||
EXPORT_SYMBOL_GPL(__ktime_divns);
|
||||
#endif /* BITS_PER_LONG >= 64 */
|
||||
|
||||
/*
|
||||
|
|
|
@ -488,13 +488,13 @@ static void sync_cmos_clock(struct work_struct *work)
|
|||
|
||||
getnstimeofday64(&now);
|
||||
if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) {
|
||||
struct timespec adjust = timespec64_to_timespec(now);
|
||||
struct timespec64 adjust = now;
|
||||
|
||||
fail = -ENODEV;
|
||||
if (persistent_clock_is_local)
|
||||
adjust.tv_sec -= (sys_tz.tz_minuteswest * 60);
|
||||
#ifdef CONFIG_GENERIC_CMOS_UPDATE
|
||||
fail = update_persistent_clock(adjust);
|
||||
fail = update_persistent_clock(timespec64_to_timespec(adjust));
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_SYSTOHC
|
||||
if (fail == -ENODEV)
|
||||
|
|
|
@ -1659,24 +1659,24 @@ void update_wall_time(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* getboottime - Return the real time of system boot.
|
||||
* @ts: pointer to the timespec to be set
|
||||
* getboottime64 - Return the real time of system boot.
|
||||
* @ts: pointer to the timespec64 to be set
|
||||
*
|
||||
* Returns the wall-time of boot in a timespec.
|
||||
* Returns the wall-time of boot in a timespec64.
|
||||
*
|
||||
* This is based on the wall_to_monotonic offset and the total suspend
|
||||
* time. Calls to settimeofday will affect the value returned (which
|
||||
* basically means that however wrong your real time clock is at boot time,
|
||||
* you get the right time here).
|
||||
*/
|
||||
void getboottime(struct timespec *ts)
|
||||
void getboottime64(struct timespec64 *ts)
|
||||
{
|
||||
struct timekeeper *tk = &tk_core.timekeeper;
|
||||
ktime_t t = ktime_sub(tk->offs_real, tk->offs_boot);
|
||||
|
||||
*ts = ktime_to_timespec(t);
|
||||
*ts = ktime_to_timespec64(t);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(getboottime);
|
||||
EXPORT_SYMBOL_GPL(getboottime64);
|
||||
|
||||
unsigned long get_seconds(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user