Branch data Line data Source code
1 : : /*
2 : : * RTC subsystem, initialize system time on startup
3 : : *
4 : : * Copyright (C) 2005 Tower Technologies
5 : : * Author: Alessandro Zummo <a.zummo@towertech.it>
6 : : *
7 : : * This program is free software; you can redistribute it and/or modify
8 : : * it under the terms of the GNU General Public License version 2 as
9 : : * published by the Free Software Foundation.
10 : : */
11 : :
12 : : #include <linux/rtc.h>
13 : :
14 : : /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
15 : : * whether it stores the most close value or the value with partial
16 : : * seconds truncated. However, it is important that we use it to store
17 : : * the truncated value. This is because otherwise it is necessary,
18 : : * in an rtc sync function, to read both xtime.tv_sec and
19 : : * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read
20 : : * of >32bits is not possible. So storing the most close value would
21 : : * slow down the sync API. So here we have the truncated value and
22 : : * the best guess is to add 0.5s.
23 : : */
24 : :
25 : 0 : static int __init rtc_hctosys(void)
26 : : {
27 : : int err = -ENODEV;
28 : : struct rtc_time tm;
29 : 0 : struct timespec tv = {
30 : : .tv_nsec = NSEC_PER_SEC >> 1,
31 : : };
32 : 0 : struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
33 : :
34 [ # # ]: 0 : if (rtc == NULL) {
35 : 0 : pr_err("%s: unable to open rtc device (%s)\n",
36 : : __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
37 : 0 : goto err_open;
38 : : }
39 : :
40 : 0 : err = rtc_read_time(rtc, &tm);
41 [ # # ]: 0 : if (err) {
42 : 0 : dev_err(rtc->dev.parent,
43 : : "hctosys: unable to read the hardware clock\n");
44 : 0 : goto err_read;
45 : :
46 : : }
47 : :
48 : 0 : err = rtc_valid_tm(&tm);
49 [ # # ]: 0 : if (err) {
50 : 0 : dev_err(rtc->dev.parent,
51 : : "hctosys: invalid date/time\n");
52 : 0 : goto err_invalid;
53 : : }
54 : :
55 : 0 : rtc_tm_to_time(&tm, &tv.tv_sec);
56 : :
57 : 0 : err = do_settimeofday(&tv);
58 : :
59 : 0 : dev_info(rtc->dev.parent,
60 : : "setting system clock to "
61 : : "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
62 : : tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
63 : : tm.tm_hour, tm.tm_min, tm.tm_sec,
64 : : (unsigned int) tv.tv_sec);
65 : :
66 : : err_invalid:
67 : : err_read:
68 : 0 : rtc_class_close(rtc);
69 : :
70 : : err_open:
71 : 0 : rtc_hctosys_ret = err;
72 : :
73 : 0 : return err;
74 : : }
75 : :
76 : : late_initcall(rtc_hctosys);
|