1 /*
2 * linux/arch/alpha/kernel/time.c
3 *
4 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
5 *
6 * This file contains the PC-specific time handling details:
7 * reading the RTC at bootup, etc..
8 * 1994-07-02 Alan Modra
9 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
10 * 1995-03-26 Markus Kuhn
11 * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
12 * precision CMOS clock update
13 */
14 #include <linux/errno.h>
15 #include <linux/sched.h>
16 #include <linux/kernel.h>
17 #include <linux/param.h>
18 #include <linux/string.h>
19 #include <linux/mm.h>
20
21 #include <asm/segment.h>
22 #include <asm/io.h>
23
24 #include <linux/mc146818rtc.h>
25 #include <linux/timex.h>
26
27 #define TIMER_IRQ 0
28
29 static int set_rtc_mmss(unsigned long);
30
31 /*
32 * timer_interrupt() needs to keep up the real-time clock,
33 * as well as call the "do_timer()" routine every clocktick
34 */
35 void timer_interrupt(struct pt_regs * regs)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
36 {
37 /* last time the cmos clock got updated */
38 static long last_rtc_update=0;
39
40 do_timer(regs);
41
42 /*
43 * If we have an externally synchronized Linux clock, then update
44 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
45 * called as close as possible to 500 ms before the new second starts.
46 */
47 if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
48 xtime.tv_usec > 500000 - (tick >> 1) &&
49 xtime.tv_usec < 500000 + (tick >> 1))
50 if (set_rtc_mmss(xtime.tv_sec) == 0)
51 last_rtc_update = xtime.tv_sec;
52 else
53 last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
54 }
55
56 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
57 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
58 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
59 *
60 * [For the Julian calendar (which was used in Russia before 1917,
61 * Britain & colonies before 1752, anywhere else before 1582,
62 * and is still in use by some communities) leave out the
63 * -year/100+year/400 terms, and add 10.]
64 *
65 * This algorithm was first published by Gauss (I think).
66 *
67 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
68 * machines were long is 32-bit! (However, as time_t is signed, we
69 * will already get problems at other places on 2038-01-19 03:14:08)
70 */
71 static inline unsigned long mktime(unsigned int year, unsigned int mon,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
72 unsigned int day, unsigned int hour,
73 unsigned int min, unsigned int sec)
74 {
75 if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
76 mon += 12; /* Puts Feb last since it has leap day */
77 year -= 1;
78 }
79 return (((
80 (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
81 year*365 - 719499
82 )*24 + hour /* now have hours */
83 )*60 + min /* now have minutes */
84 )*60 + sec; /* finally seconds */
85 }
86
87 void time_init(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
88 {
89 unsigned int year, mon, day, hour, min, sec;
90 int i;
91
92 /* The Linux interpretation of the CMOS clock register contents:
93 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
94 * RTC registers show the second which has precisely just started.
95 * Let's hope other operating systems interpret the RTC the same way.
96 */
97 /* read RTC exactly on falling edge of update flag */
98 for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
99 if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
100 break;
101 for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
102 if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
103 break;
104 do { /* Isn't this overkill ? UIP above should guarantee consistency */
105 sec = CMOS_READ(RTC_SECONDS);
106 min = CMOS_READ(RTC_MINUTES);
107 hour = CMOS_READ(RTC_HOURS);
108 day = CMOS_READ(RTC_DAY_OF_MONTH);
109 mon = CMOS_READ(RTC_MONTH);
110 year = CMOS_READ(RTC_YEAR);
111 } while (sec != CMOS_READ(RTC_SECONDS));
112 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
113 {
114 BCD_TO_BIN(sec);
115 BCD_TO_BIN(min);
116 BCD_TO_BIN(hour);
117 BCD_TO_BIN(day);
118 BCD_TO_BIN(mon);
119 BCD_TO_BIN(year);
120 }
121 #ifdef ALPHA_PRE_V1_2_SRM_CONSOLE
122 /*
123 * The meaning of life, the universe, and everything. Plus
124 * this makes the year come out right on SRM consoles earlier
125 * than v1.2.
126 */
127 year -= 42;
128 #endif
129 if ((year += 1900) < 1970)
130 year += 100;
131 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
132 xtime.tv_usec = 0;
133 }
134
135 /*
136 * We could get better timer accuracy by using the alpha
137 * time counters or something. Now this is limited to
138 * the HZ clock frequency.
139 */
140 void do_gettimeofday(struct timeval *tv)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
141 {
142 unsigned long flags;
143
144 save_flags(flags);
145 cli();
146 *tv = xtime;
147 restore_flags(flags);
148 }
149
150 void do_settimeofday(struct timeval *tv)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
151 {
152 cli();
153 xtime = *tv;
154 time_state = TIME_BAD;
155 time_maxerror = 0x70000000;
156 time_esterror = 0x70000000;
157 sti();
158 }
159
160
161 /*
162 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
163 * called 500 ms after the second nowtime has started, because when
164 * nowtime is written into the registers of the CMOS clock, it will
165 * jump to the next second precisely 500 ms later. Check the Motorola
166 * MC146818A or Dallas DS12887 data sheet for details.
167 */
168 static int set_rtc_mmss(unsigned long nowtime)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
169 {
170 int retval = 0;
171 int real_seconds, real_minutes, cmos_minutes;
172 unsigned char save_control, save_freq_select;
173
174 save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
175 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
176
177 save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
178 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
179
180 cmos_minutes = CMOS_READ(RTC_MINUTES);
181 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
182 BCD_TO_BIN(cmos_minutes);
183
184 /*
185 * since we're only adjusting minutes and seconds,
186 * don't interfere with hour overflow. This avoids
187 * messing with unknown time zones but requires your
188 * RTC not to be off by more than 15 minutes
189 */
190 real_seconds = nowtime % 60;
191 real_minutes = nowtime / 60;
192 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
193 real_minutes += 30; /* correct for half hour time zone */
194 real_minutes %= 60;
195
196 if (abs(real_minutes - cmos_minutes) < 30) {
197 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
198 BIN_TO_BCD(real_seconds);
199 BIN_TO_BCD(real_minutes);
200 }
201 CMOS_WRITE(real_seconds,RTC_SECONDS);
202 CMOS_WRITE(real_minutes,RTC_MINUTES);
203 } else
204 retval = -1;
205
206 /* The following flags have to be released exactly in this order,
207 * otherwise the DS12887 (popular MC146818A clone with integrated
208 * battery and quartz) will not reset the oscillator and will not
209 * update precisely 500 ms later. You won't find this mentioned in
210 * the Dallas Semiconductor data sheets, but who believes data
211 * sheets anyway ... -- Markus Kuhn
212 */
213 CMOS_WRITE(save_control, RTC_CONTROL);
214 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
215
216 return retval;
217 }