This source file includes following definitions.
- rpcc
- timer_interrupt
- mktime
- time_init
- do_gettimeofday
- do_settimeofday
- set_rtc_mmss
1
2
3
4
5
6
7
8
9
10
11
12
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 #include <asm/hwrpb.h>
24
25 #include <linux/mc146818rtc.h>
26 #include <linux/timex.h>
27
28 #define TIMER_IRQ 0
29
30 extern struct hwrpb_struct *hwrpb;
31
32 static int set_rtc_mmss(unsigned long);
33
34
35
36
37
38
39
40 #define FIX_SHIFT 48
41
42
43 static struct {
44 __u32 last_time;
45 __u32 max_cycles_per_tick;
46 unsigned long scaled_ticks_per_cycle;
47 long last_rtc_update;
48 } state;
49
50
51 static inline __u32 rpcc(void)
52 {
53 __u32 result;
54
55 asm volatile ("rpcc %0" : "r="(result));
56 return result;
57 }
58
59
60
61
62
63
64 void timer_interrupt(struct pt_regs * regs)
65 {
66 __u32 delta, now;
67
68 now = rpcc();
69 delta = now - state.last_time;
70 state.last_time = now;
71 if (delta > state.max_cycles_per_tick) {
72 int i, missed_ticks;
73
74 missed_ticks = ((delta * state.scaled_ticks_per_cycle) >> FIX_SHIFT) - 1;
75 for (i = 0; i < missed_ticks; ++i) {
76 do_timer(regs);
77 }
78 }
79 do_timer(regs);
80
81
82
83
84
85
86 if (time_state != TIME_BAD && xtime.tv_sec > state.last_rtc_update + 660 &&
87 xtime.tv_usec > 500000 - (tick >> 1) &&
88 xtime.tv_usec < 500000 + (tick >> 1))
89 if (set_rtc_mmss(xtime.tv_sec) == 0)
90 state.last_rtc_update = xtime.tv_sec;
91 else
92 state.last_rtc_update = xtime.tv_sec - 600;
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 static inline unsigned long mktime(unsigned int year, unsigned int mon,
111 unsigned int day, unsigned int hour,
112 unsigned int min, unsigned int sec)
113 {
114 if (0 >= (int) (mon -= 2)) {
115 mon += 12;
116 year -= 1;
117 }
118 return (((
119 (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
120 year*365 - 719499
121 )*24 + hour
122 )*60 + min
123 )*60 + sec;
124 }
125
126 void time_init(void)
127 {
128 unsigned int year, mon, day, hour, min, sec;
129 int i;
130
131
132
133
134
135
136
137 for (i = 0 ; i < 1000000 ; i++)
138 if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
139 break;
140 for (i = 0 ; i < 1000000 ; i++)
141 if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
142 break;
143 do {
144 sec = CMOS_READ(RTC_SECONDS);
145 min = CMOS_READ(RTC_MINUTES);
146 hour = CMOS_READ(RTC_HOURS);
147 day = CMOS_READ(RTC_DAY_OF_MONTH);
148 mon = CMOS_READ(RTC_MONTH);
149 year = CMOS_READ(RTC_YEAR);
150 } while (sec != CMOS_READ(RTC_SECONDS));
151 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
152 {
153 BCD_TO_BIN(sec);
154 BCD_TO_BIN(min);
155 BCD_TO_BIN(hour);
156 BCD_TO_BIN(day);
157 BCD_TO_BIN(mon);
158 BCD_TO_BIN(year);
159 }
160 #ifdef ALPHA_PRE_V1_2_SRM_CONSOLE
161
162
163
164
165
166 year -= 42;
167 #endif
168 if ((year += 1900) < 1970)
169 year += 100;
170 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
171 xtime.tv_usec = 0;
172
173 if (HZ > (1<<16)) {
174 extern void __you_loose (void);
175 __you_loose();
176 }
177 state.last_time = rpcc();
178 state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
179 state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ;
180 state.last_rtc_update = 0;
181 }
182
183
184
185
186
187
188 void do_gettimeofday(struct timeval *tv)
189 {
190 unsigned long flags;
191
192 save_flags(flags);
193 cli();
194 *tv = xtime;
195 restore_flags(flags);
196 }
197
198 void do_settimeofday(struct timeval *tv)
199 {
200 cli();
201 xtime = *tv;
202 time_state = TIME_BAD;
203 time_maxerror = 0x70000000;
204 time_esterror = 0x70000000;
205 sti();
206 }
207
208
209
210
211
212
213
214
215
216 static int set_rtc_mmss(unsigned long nowtime)
217 {
218 int retval = 0;
219 int real_seconds, real_minutes, cmos_minutes;
220 unsigned char save_control, save_freq_select;
221
222 save_control = CMOS_READ(RTC_CONTROL);
223 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
224
225 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
226 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
227
228 cmos_minutes = CMOS_READ(RTC_MINUTES);
229 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
230 BCD_TO_BIN(cmos_minutes);
231
232
233
234
235
236
237
238 real_seconds = nowtime % 60;
239 real_minutes = nowtime / 60;
240 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
241 real_minutes += 30;
242 real_minutes %= 60;
243
244 if (abs(real_minutes - cmos_minutes) < 30) {
245 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
246 BIN_TO_BCD(real_seconds);
247 BIN_TO_BCD(real_minutes);
248 }
249 CMOS_WRITE(real_seconds,RTC_SECONDS);
250 CMOS_WRITE(real_minutes,RTC_MINUTES);
251 } else
252 retval = -1;
253
254
255
256
257
258
259
260
261 CMOS_WRITE(save_control, RTC_CONTROL);
262 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
263
264 return retval;
265 }