This source file includes following definitions.
- timer_interrupt
- mktime
- time_init
- do_gettimeofday
- do_settimeofday
- set_rtc_mmss
1
2
3
4
5
6
7
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
11 #include <linux/param.h>
12 #include <linux/string.h>
13 #include <linux/mm.h>
14 #include <linux/timex.h>
15
16 #include <asm/oplib.h>
17 #include <asm/segment.h>
18 #include <asm/timer.h>
19 #include <asm/mostek.h>
20
21 #define TIMER_IRQ 10
22
23 static int set_rtc_mmss(unsigned long);
24
25
26
27
28
29 void timer_interrupt(int irq, struct pt_regs * regs)
30 {
31
32 static long last_rtc_update=0;
33 volatile unsigned int clear_intr;
34
35
36 clear_intr = *master_l10_limit;
37
38 do_timer(regs);
39
40
41 if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
42 xtime.tv_usec > 500000 - (tick >> 1) &&
43 xtime.tv_usec < 500000 + (tick >> 1))
44 if (set_rtc_mmss(xtime.tv_sec) == 0)
45 last_rtc_update = xtime.tv_sec;
46 else
47 last_rtc_update = xtime.tv_sec - 600;
48 }
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 static inline unsigned long mktime(unsigned int year, unsigned int mon,
66 unsigned int day, unsigned int hour,
67 unsigned int min, unsigned int sec)
68 {
69 if (0 >= (int) (mon -= 2)) {
70 mon += 12;
71 year -= 1;
72 }
73 return (((
74 (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
75 year*365 - 719499
76 )*24 + hour
77 )*60 + min
78 )*60 + sec;
79 }
80
81 #ifndef BCD_TO_BIN
82 #define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
83 #endif
84
85 #ifndef BIN_TO_BCD
86 #define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
87 #endif
88
89 void time_init(void)
90 {
91 unsigned int year, mon, day, hour, min, sec;
92 struct mostek48t02 *mregs;
93
94 request_irq(TIMER_IRQ, timer_interrupt, SA_INTERRUPT, "timer");
95 mregs = mstk48t02_regs;
96 if(!mregs) {
97 prom_printf("Something wrong, clock regs not mapped yet.\n");
98 prom_halt();
99 }
100 mregs->creg |= MSTK_CREG_READ;
101 sec = BCD_TO_BIN(mregs->sec);
102 min = BCD_TO_BIN(mregs->min);
103 hour = BCD_TO_BIN(mregs->hour);
104 day = BCD_TO_BIN(mregs->dom);
105 mon = BCD_TO_BIN(mregs->mnth);
106 year = (BCD_TO_BIN(mregs->yr) + MSTK_YR_ZERO);
107 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
108 xtime.tv_usec = 0;
109 mregs->creg &= ~MSTK_CREG_READ;
110 return;
111 }
112
113 void do_gettimeofday(struct timeval *tv)
114 {
115 unsigned long flags;
116
117 save_flags(flags);
118 cli();
119 *tv = xtime;
120 restore_flags(flags);
121 }
122
123 void do_settimeofday(struct timeval *tv)
124 {
125 cli();
126 xtime = *tv;
127 time_state = TIME_BAD;
128 time_maxerror = 0x70000000;
129 time_esterror = 0x70000000;
130 sti();
131 }
132
133 static int set_rtc_mmss(unsigned long nowtime)
134 {
135 int retval = 0;
136 int real_seconds, real_minutes, mostek_minutes;
137 struct mostek48t02 *mregs = mstk48t02_regs;
138
139 if(!mregs)
140 retval = -1;
141 else {
142 mregs->creg |= MSTK_CREG_READ;
143 mostek_minutes = BCD_TO_BIN(mregs->min);
144 mregs->creg &= ~MSTK_CREG_READ;
145
146 real_seconds = nowtime % 60;
147 real_minutes = nowtime / 60;
148 if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
149 real_minutes += 30;
150 real_minutes %= 60;
151 if (abs(real_minutes - mostek_minutes) < 30) {
152 mregs->creg |= MSTK_CREG_WRITE;
153 mregs->sec = real_seconds;
154 mregs->min = real_minutes;
155 mregs->creg &= ~MSTK_CREG_WRITE;
156 } else
157 retval = -1;
158 }
159
160 return retval;
161 }