mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-30 11:04:25 +00:00
MIPS: Convert update_persistent_clock() to update_persistent_clock64()
Since struct timespec is not y2038 safe on 32bit machines, this patch converts update_persistent_clock() to update_persistent_clock64() using struct timespec64. The rtc_mips_set_time() and rtc_mips_set_mmss() interfaces were using 'unsigned long' type that is not y2038 safe on 32bit machines, moreover there is only one platform implementing rtc_mips_set_time() and two platforms implementing rtc_mips_set_mmss(), so we can just make them each implement update_persistent_clock64() directly, to get that helper out of the common mips code by removing rtc_mips_set_time() and rtc_mips_set_mmss() interfaces. Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Acked-by: Arnd Bergmann <arnd@arndb.de> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Huacai Chen <chenhc@lemote.com> Cc: Paul Burton <paul.burton@mips.com> Cc: linux-mips@linux-mips.org Signed-off-by: James Hogan <jhogan@kernel.org>
This commit is contained in:
parent
09adad1719
commit
f06e7aa47f
8 changed files with 30 additions and 39 deletions
|
@ -59,14 +59,15 @@ void read_persistent_clock64(struct timespec64 *ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In order to set the CMOS clock precisely, rtc_mips_set_mmss has to
|
* In order to set the CMOS clock precisely, update_persistent_clock64 has to
|
||||||
* be called 500 ms after the second nowtime has started, because when
|
* be called 500 ms after the second nowtime has started, because when
|
||||||
* nowtime is written into the registers of the CMOS clock, it will
|
* nowtime is written into the registers of the CMOS clock, it will
|
||||||
* jump to the next second precisely 500 ms later. Check the Dallas
|
* jump to the next second precisely 500 ms later. Check the Dallas
|
||||||
* DS1287 data sheet for details.
|
* DS1287 data sheet for details.
|
||||||
*/
|
*/
|
||||||
int rtc_mips_set_mmss(unsigned long nowtime)
|
int update_persistent_clock64(struct timespec64 now)
|
||||||
{
|
{
|
||||||
|
time64_t nowtime = now.tv_sec;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int real_seconds, real_minutes, cmos_minutes;
|
int real_seconds, real_minutes, cmos_minutes;
|
||||||
unsigned char save_control, save_freq_select;
|
unsigned char save_control, save_freq_select;
|
||||||
|
@ -91,8 +92,7 @@ int rtc_mips_set_mmss(unsigned long nowtime)
|
||||||
* messing with unknown time zones but requires your
|
* messing with unknown time zones but requires your
|
||||||
* RTC not to be off by more than 15 minutes
|
* RTC not to be off by more than 15 minutes
|
||||||
*/
|
*/
|
||||||
real_seconds = nowtime % 60;
|
real_minutes = div_s64_rem(nowtime, 60, &real_seconds);
|
||||||
real_minutes = nowtime / 60;
|
|
||||||
if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
|
if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
|
||||||
real_minutes += 30; /* correct for half hour time zone */
|
real_minutes += 30; /* correct for half hour time zone */
|
||||||
real_minutes %= 60;
|
real_minutes %= 60;
|
||||||
|
|
|
@ -21,15 +21,6 @@
|
||||||
|
|
||||||
extern spinlock_t rtc_lock;
|
extern spinlock_t rtc_lock;
|
||||||
|
|
||||||
/*
|
|
||||||
* RTC ops. By default, they point to weak no-op RTC functions.
|
|
||||||
* rtc_mips_set_time - reverse the above translation and set time to RTC.
|
|
||||||
* rtc_mips_set_mmss - similar to rtc_set_time, but only min and sec need
|
|
||||||
* to be set. Used by RTC sync-up.
|
|
||||||
*/
|
|
||||||
extern int rtc_mips_set_time(unsigned long);
|
|
||||||
extern int rtc_mips_set_mmss(unsigned long);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* board specific routines required by time_init().
|
* board specific routines required by time_init().
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -34,21 +34,6 @@
|
||||||
DEFINE_SPINLOCK(rtc_lock);
|
DEFINE_SPINLOCK(rtc_lock);
|
||||||
EXPORT_SYMBOL(rtc_lock);
|
EXPORT_SYMBOL(rtc_lock);
|
||||||
|
|
||||||
int __weak rtc_mips_set_time(unsigned long sec)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __weak rtc_mips_set_mmss(unsigned long nowtime)
|
|
||||||
{
|
|
||||||
return rtc_mips_set_time(nowtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
int update_persistent_clock(struct timespec now)
|
|
||||||
{
|
|
||||||
return rtc_mips_set_mmss(now.tv_sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int null_perf_irq(void)
|
static int null_perf_irq(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -152,14 +152,19 @@ void read_persistent_clock64(struct timespec64 *ts)
|
||||||
ts->tv_nsec = 0;
|
ts->tv_nsec = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtc_mips_set_mmss(unsigned long time)
|
int update_persistent_clock64(struct timespec64 now)
|
||||||
{
|
{
|
||||||
|
time64_t time = now.tv_sec;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&rtc_lock, flags);
|
spin_lock_irqsave(&rtc_lock, flags);
|
||||||
rtc_init_op();
|
rtc_init_op();
|
||||||
rtc_write_byte(SET_TIME_CMD);
|
rtc_write_byte(SET_TIME_CMD);
|
||||||
rtc_write_word(time);
|
/*
|
||||||
|
* Due to the hardware limitation, we cast to 'unsigned long' type,
|
||||||
|
* so it will overflow in year 2106 on 32-bit machine.
|
||||||
|
*/
|
||||||
|
rtc_write_word((unsigned long)time);
|
||||||
rtc_end_op();
|
rtc_end_op();
|
||||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,16 @@ int proc_dolasatrtc(struct ctl_table *table, int write,
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (write)
|
if (write) {
|
||||||
rtc_mips_set_mmss(rtctmp);
|
/*
|
||||||
|
* Due to the RTC hardware limitation, we can not actually
|
||||||
|
* use the full 64-bit range here.
|
||||||
|
*/
|
||||||
|
ts.tv_sec = rtctmp;
|
||||||
|
ts.tv_nsec = 0;
|
||||||
|
|
||||||
|
update_persistent_clock64(ts);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,13 +141,13 @@ static int m41t81_write(uint8_t addr, int b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int m41t81_set_time(unsigned long t)
|
int m41t81_set_time(time64_t t)
|
||||||
{
|
{
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/* Note we don't care about the century */
|
/* Note we don't care about the century */
|
||||||
rtc_time_to_tm(t, &tm);
|
rtc_time64_to_tm(t, &tm);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note the write order matters as it ensures the correctness.
|
* Note the write order matters as it ensures the correctness.
|
||||||
|
|
|
@ -109,13 +109,13 @@ static int xicor_write(uint8_t addr, int b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int xicor_set_time(unsigned long t)
|
int xicor_set_time(time64_t t)
|
||||||
{
|
{
|
||||||
struct rtc_time tm;
|
struct rtc_time tm;
|
||||||
int tmp;
|
int tmp;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
rtc_time_to_tm(t, &tm);
|
rtc_time64_to_tm(t, &tm);
|
||||||
tm.tm_year += 1900;
|
tm.tm_year += 1900;
|
||||||
|
|
||||||
spin_lock_irqsave(&rtc_lock, flags);
|
spin_lock_irqsave(&rtc_lock, flags);
|
||||||
|
|
|
@ -57,11 +57,11 @@ extern void sb1250_setup(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int xicor_probe(void);
|
extern int xicor_probe(void);
|
||||||
extern int xicor_set_time(unsigned long);
|
extern int xicor_set_time(time64_t);
|
||||||
extern time64_t xicor_get_time(void);
|
extern time64_t xicor_get_time(void);
|
||||||
|
|
||||||
extern int m41t81_probe(void);
|
extern int m41t81_probe(void);
|
||||||
extern int m41t81_set_time(unsigned long);
|
extern int m41t81_set_time(time64_t);
|
||||||
extern time64_t m41t81_get_time(void);
|
extern time64_t m41t81_get_time(void);
|
||||||
|
|
||||||
const char *get_system_type(void)
|
const char *get_system_type(void)
|
||||||
|
@ -109,8 +109,10 @@ void read_persistent_clock64(struct timespec64 *ts)
|
||||||
ts->tv_nsec = 0;
|
ts->tv_nsec = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtc_mips_set_time(unsigned long sec)
|
int update_persistent_clock64(struct timespec64 now)
|
||||||
{
|
{
|
||||||
|
time64_t sec = now.tv_sec;
|
||||||
|
|
||||||
switch (swarm_rtc_type) {
|
switch (swarm_rtc_type) {
|
||||||
case RTC_XICOR:
|
case RTC_XICOR:
|
||||||
return xicor_set_time(sec);
|
return xicor_set_time(sec);
|
||||||
|
|
Loading…
Add table
Reference in a new issue