|
@@ -16,6 +16,7 @@
|
|
|
#include <linux/mm.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/rtc.h>
|
|
|
+#include <linux/math64.h>
|
|
|
|
|
|
#include "ntp_internal.h"
|
|
|
#include "timekeeping_internal.h"
|
|
@@ -394,10 +395,11 @@ ktime_t ntp_get_next_leap(void)
|
|
|
*
|
|
|
* Also handles leap second processing, and returns leap offset
|
|
|
*/
|
|
|
-int second_overflow(unsigned long secs)
|
|
|
+int second_overflow(time64_t secs)
|
|
|
{
|
|
|
s64 delta;
|
|
|
int leap = 0;
|
|
|
+ s32 rem;
|
|
|
|
|
|
/*
|
|
|
* Leap second processing. If in leap-insert state at the end of the
|
|
@@ -408,19 +410,19 @@ int second_overflow(unsigned long secs)
|
|
|
case TIME_OK:
|
|
|
if (time_status & STA_INS) {
|
|
|
time_state = TIME_INS;
|
|
|
- ntp_next_leap_sec = secs + SECS_PER_DAY -
|
|
|
- (secs % SECS_PER_DAY);
|
|
|
+ div_s64_rem(secs, SECS_PER_DAY, &rem);
|
|
|
+ ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
|
|
|
} else if (time_status & STA_DEL) {
|
|
|
time_state = TIME_DEL;
|
|
|
- ntp_next_leap_sec = secs + SECS_PER_DAY -
|
|
|
- ((secs+1) % SECS_PER_DAY);
|
|
|
+ div_s64_rem(secs + 1, SECS_PER_DAY, &rem);
|
|
|
+ ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
|
|
|
}
|
|
|
break;
|
|
|
case TIME_INS:
|
|
|
if (!(time_status & STA_INS)) {
|
|
|
ntp_next_leap_sec = TIME64_MAX;
|
|
|
time_state = TIME_OK;
|
|
|
- } else if (secs % SECS_PER_DAY == 0) {
|
|
|
+ } else if (secs == ntp_next_leap_sec) {
|
|
|
leap = -1;
|
|
|
time_state = TIME_OOP;
|
|
|
printk(KERN_NOTICE
|
|
@@ -431,7 +433,7 @@ int second_overflow(unsigned long secs)
|
|
|
if (!(time_status & STA_DEL)) {
|
|
|
ntp_next_leap_sec = TIME64_MAX;
|
|
|
time_state = TIME_OK;
|
|
|
- } else if ((secs + 1) % SECS_PER_DAY == 0) {
|
|
|
+ } else if (secs == ntp_next_leap_sec) {
|
|
|
leap = 1;
|
|
|
ntp_next_leap_sec = TIME64_MAX;
|
|
|
time_state = TIME_WAIT;
|