mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 06:12:08 +00:00
4c24e29e65
Without this patch /sys/class/rtc/$CONFIG_RTC_HCTOSYS_DEVICE/hctosys contains a 1 (meaning "This rtc was used to initialize the system clock") even if setting the time by do_settimeofday() at bootup failed. The RTC can also be used to set the clock on resume, if it did 1, otherwise 0. Previously there was no indication if the RTC was used to set the clock in resume. This uses only CONFIG_RTC_HCTOSYS_DEVICE for conditional compilation instead of it and CONFIG_RTC_HCTOSYS to be more consistent. rtc_hctosys_ret was moved to class.c so class.c no longer depends on hctosys.c. [sfr@canb.auug.org.au: fix build] Signed-off-by: David Fries <David@Fries.net> Cc: Matthew Garrett <mjg@redhat.com> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
77 lines
1.9 KiB
C
77 lines
1.9 KiB
C
/*
|
|
* RTC subsystem, initialize system time on startup
|
|
*
|
|
* Copyright (C) 2005 Tower Technologies
|
|
* Author: Alessandro Zummo <a.zummo@towertech.it>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/rtc.h>
|
|
|
|
/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
|
|
* whether it stores the most close value or the value with partial
|
|
* seconds truncated. However, it is important that we use it to store
|
|
* the truncated value. This is because otherwise it is necessary,
|
|
* in an rtc sync function, to read both xtime.tv_sec and
|
|
* xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
|
|
* of >32bits is not possible. So storing the most close value would
|
|
* slow down the sync API. So here we have the truncated value and
|
|
* the best guess is to add 0.5s.
|
|
*/
|
|
|
|
static int __init rtc_hctosys(void)
|
|
{
|
|
int err = -ENODEV;
|
|
struct rtc_time tm;
|
|
struct timespec tv = {
|
|
.tv_nsec = NSEC_PER_SEC >> 1,
|
|
};
|
|
struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
|
|
|
|
if (rtc == NULL) {
|
|
pr_err("%s: unable to open rtc device (%s)\n",
|
|
__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
|
|
goto err_open;
|
|
}
|
|
|
|
err = rtc_read_time(rtc, &tm);
|
|
if (err) {
|
|
dev_err(rtc->dev.parent,
|
|
"hctosys: unable to read the hardware clock\n");
|
|
goto err_read;
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
err = do_settimeofday(&tv);
|
|
|
|
dev_info(rtc->dev.parent,
|
|
"setting system clock to "
|
|
"%d-%02d-%02d %02d:%02d:%02d UTC (%u)\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);
|
|
|
|
err_invalid:
|
|
err_read:
|
|
rtc_class_close(rtc);
|
|
|
|
err_open:
|
|
rtc_hctosys_ret = err;
|
|
|
|
return err;
|
|
}
|
|
|
|
late_initcall(rtc_hctosys);
|