• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/bcd.h>
3 #include <linux/delay.h>
4 #include <linux/export.h>
5 #include <linux/mc146818rtc.h>
6 
7 #ifdef CONFIG_ACPI
8 #include <linux/acpi.h>
9 #endif
10 
11 /*
12  * Execute a function while the UIP (Update-in-progress) bit of the RTC is
13  * unset.
14  *
15  * Warning: callback may be executed more then once.
16  */
mc146818_avoid_UIP(void (* callback)(unsigned char seconds,void * param),void * param)17 bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
18 			void *param)
19 {
20 	int i;
21 	unsigned long flags;
22 	unsigned char seconds;
23 
24 	for (i = 0; i < 10; i++) {
25 		spin_lock_irqsave(&rtc_lock, flags);
26 
27 		/*
28 		 * Check whether there is an update in progress during which the
29 		 * readout is unspecified. The maximum update time is ~2ms. Poll
30 		 * every msec for completion.
31 		 *
32 		 * Store the second value before checking UIP so a long lasting
33 		 * NMI which happens to hit after the UIP check cannot make
34 		 * an update cycle invisible.
35 		 */
36 		seconds = CMOS_READ(RTC_SECONDS);
37 
38 		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
39 			spin_unlock_irqrestore(&rtc_lock, flags);
40 			mdelay(1);
41 			continue;
42 		}
43 
44 		/* Revalidate the above readout */
45 		if (seconds != CMOS_READ(RTC_SECONDS)) {
46 			spin_unlock_irqrestore(&rtc_lock, flags);
47 			continue;
48 		}
49 
50 		if (callback)
51 			callback(seconds, param);
52 
53 		/*
54 		 * Check for the UIP bit again. If it is set now then
55 		 * the above values may contain garbage.
56 		 */
57 		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
58 			spin_unlock_irqrestore(&rtc_lock, flags);
59 			mdelay(1);
60 			continue;
61 		}
62 
63 		/*
64 		 * A NMI might have interrupted the above sequence so check
65 		 * whether the seconds value has changed which indicates that
66 		 * the NMI took longer than the UIP bit was set. Unlikely, but
67 		 * possible and there is also virt...
68 		 */
69 		if (seconds != CMOS_READ(RTC_SECONDS)) {
70 			spin_unlock_irqrestore(&rtc_lock, flags);
71 			continue;
72 		}
73 		spin_unlock_irqrestore(&rtc_lock, flags);
74 
75 		return true;
76 	}
77 	return false;
78 }
79 EXPORT_SYMBOL_GPL(mc146818_avoid_UIP);
80 
81 /*
82  * If the UIP (Update-in-progress) bit of the RTC is set for more then
83  * 10ms, the RTC is apparently broken or not present.
84  */
mc146818_does_rtc_work(void)85 bool mc146818_does_rtc_work(void)
86 {
87 	int i;
88 	unsigned char val;
89 	unsigned long flags;
90 
91 	for (i = 0; i < 10; i++) {
92 		spin_lock_irqsave(&rtc_lock, flags);
93 		val = CMOS_READ(RTC_FREQ_SELECT);
94 		spin_unlock_irqrestore(&rtc_lock, flags);
95 
96 		if ((val & RTC_UIP) == 0)
97 			return true;
98 
99 		mdelay(1);
100 	}
101 
102 	return false;
103 }
104 EXPORT_SYMBOL_GPL(mc146818_does_rtc_work);
105 
mc146818_get_time(struct rtc_time * time)106 int mc146818_get_time(struct rtc_time *time)
107 {
108 	unsigned char ctrl;
109 	unsigned long flags;
110 	unsigned int iter_count = 0;
111 	unsigned char century = 0;
112 	bool retry;
113 
114 #ifdef CONFIG_MACH_DECSTATION
115 	unsigned int real_year;
116 #endif
117 
118 again:
119 	if (iter_count > 10) {
120 		memset(time, 0, sizeof(*time));
121 		return -EIO;
122 	}
123 	iter_count++;
124 
125 	spin_lock_irqsave(&rtc_lock, flags);
126 
127 	/*
128 	 * Check whether there is an update in progress during which the
129 	 * readout is unspecified. The maximum update time is ~2ms. Poll
130 	 * every msec for completion.
131 	 *
132 	 * Store the second value before checking UIP so a long lasting NMI
133 	 * which happens to hit after the UIP check cannot make an update
134 	 * cycle invisible.
135 	 */
136 	time->tm_sec = CMOS_READ(RTC_SECONDS);
137 
138 	if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
139 		spin_unlock_irqrestore(&rtc_lock, flags);
140 		mdelay(1);
141 		goto again;
142 	}
143 
144 	/* Revalidate the above readout */
145 	if (time->tm_sec != CMOS_READ(RTC_SECONDS)) {
146 		spin_unlock_irqrestore(&rtc_lock, flags);
147 		goto again;
148 	}
149 
150 	/*
151 	 * Only the values that we read from the RTC are set. We leave
152 	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
153 	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
154 	 * by the RTC when initially set to a non-zero value.
155 	 */
156 	time->tm_min = CMOS_READ(RTC_MINUTES);
157 	time->tm_hour = CMOS_READ(RTC_HOURS);
158 	time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
159 	time->tm_mon = CMOS_READ(RTC_MONTH);
160 	time->tm_year = CMOS_READ(RTC_YEAR);
161 #ifdef CONFIG_MACH_DECSTATION
162 	real_year = CMOS_READ(RTC_DEC_YEAR);
163 #endif
164 #ifdef CONFIG_ACPI
165 	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
166 	    acpi_gbl_FADT.century)
167 		century = CMOS_READ(acpi_gbl_FADT.century);
168 #endif
169 	ctrl = CMOS_READ(RTC_CONTROL);
170 	/*
171 	 * Check for the UIP bit again. If it is set now then
172 	 * the above values may contain garbage.
173 	 */
174 	retry = CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP;
175 	/*
176 	 * A NMI might have interrupted the above sequence so check whether
177 	 * the seconds value has changed which indicates that the NMI took
178 	 * longer than the UIP bit was set. Unlikely, but possible and
179 	 * there is also virt...
180 	 */
181 	retry |= time->tm_sec != CMOS_READ(RTC_SECONDS);
182 
183 	spin_unlock_irqrestore(&rtc_lock, flags);
184 
185 	if (retry)
186 		goto again;
187 
188 	if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
189 	{
190 		time->tm_sec = bcd2bin(time->tm_sec);
191 		time->tm_min = bcd2bin(time->tm_min);
192 		time->tm_hour = bcd2bin(time->tm_hour);
193 		time->tm_mday = bcd2bin(time->tm_mday);
194 		time->tm_mon = bcd2bin(time->tm_mon);
195 		time->tm_year = bcd2bin(time->tm_year);
196 		century = bcd2bin(century);
197 	}
198 
199 #ifdef CONFIG_MACH_DECSTATION
200 	time->tm_year += real_year - 72;
201 #endif
202 
203 	if (century > 19)
204 		time->tm_year += (century - 19) * 100;
205 
206 	/*
207 	 * Account for differences between how the RTC uses the values
208 	 * and how they are defined in a struct rtc_time;
209 	 */
210 	if (time->tm_year <= 69)
211 		time->tm_year += 100;
212 
213 	time->tm_mon--;
214 
215 	return 0;
216 }
217 EXPORT_SYMBOL_GPL(mc146818_get_time);
218 
219 /* AMD systems don't allow access to AltCentury with DV1 */
apply_amd_register_a_behavior(void)220 static bool apply_amd_register_a_behavior(void)
221 {
222 #ifdef CONFIG_X86
223 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
224 	    boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
225 		return true;
226 #endif
227 	return false;
228 }
229 
230 /* Set the current date and time in the real time clock. */
mc146818_set_time(struct rtc_time * time)231 int mc146818_set_time(struct rtc_time *time)
232 {
233 	unsigned long flags;
234 	unsigned char mon, day, hrs, min, sec;
235 	unsigned char save_control, save_freq_select;
236 	unsigned int yrs;
237 #ifdef CONFIG_MACH_DECSTATION
238 	unsigned int real_yrs, leap_yr;
239 #endif
240 	unsigned char century = 0;
241 
242 	yrs = time->tm_year;
243 	mon = time->tm_mon + 1;   /* tm_mon starts at zero */
244 	day = time->tm_mday;
245 	hrs = time->tm_hour;
246 	min = time->tm_min;
247 	sec = time->tm_sec;
248 
249 	if (yrs > 255)	/* They are unsigned */
250 		return -EINVAL;
251 
252 #ifdef CONFIG_MACH_DECSTATION
253 	real_yrs = yrs;
254 	leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
255 			!((yrs + 1900) % 400));
256 	yrs = 72;
257 
258 	/*
259 	 * We want to keep the year set to 73 until March
260 	 * for non-leap years, so that Feb, 29th is handled
261 	 * correctly.
262 	 */
263 	if (!leap_yr && mon < 3) {
264 		real_yrs--;
265 		yrs = 73;
266 	}
267 #endif
268 
269 #ifdef CONFIG_ACPI
270 	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
271 	    acpi_gbl_FADT.century) {
272 		century = (yrs + 1900) / 100;
273 		yrs %= 100;
274 	}
275 #endif
276 
277 	/* These limits and adjustments are independent of
278 	 * whether the chip is in binary mode or not.
279 	 */
280 	if (yrs > 169)
281 		return -EINVAL;
282 
283 	if (yrs >= 100)
284 		yrs -= 100;
285 
286 	spin_lock_irqsave(&rtc_lock, flags);
287 	save_control = CMOS_READ(RTC_CONTROL);
288 	spin_unlock_irqrestore(&rtc_lock, flags);
289 	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
290 		sec = bin2bcd(sec);
291 		min = bin2bcd(min);
292 		hrs = bin2bcd(hrs);
293 		day = bin2bcd(day);
294 		mon = bin2bcd(mon);
295 		yrs = bin2bcd(yrs);
296 		century = bin2bcd(century);
297 	}
298 
299 	spin_lock_irqsave(&rtc_lock, flags);
300 	save_control = CMOS_READ(RTC_CONTROL);
301 	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
302 	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
303 	if (apply_amd_register_a_behavior())
304 		CMOS_WRITE((save_freq_select & ~RTC_AMD_BANK_SELECT), RTC_FREQ_SELECT);
305 	else
306 		CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
307 
308 #ifdef CONFIG_MACH_DECSTATION
309 	CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
310 #endif
311 	CMOS_WRITE(yrs, RTC_YEAR);
312 	CMOS_WRITE(mon, RTC_MONTH);
313 	CMOS_WRITE(day, RTC_DAY_OF_MONTH);
314 	CMOS_WRITE(hrs, RTC_HOURS);
315 	CMOS_WRITE(min, RTC_MINUTES);
316 	CMOS_WRITE(sec, RTC_SECONDS);
317 #ifdef CONFIG_ACPI
318 	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
319 	    acpi_gbl_FADT.century)
320 		CMOS_WRITE(century, acpi_gbl_FADT.century);
321 #endif
322 
323 	CMOS_WRITE(save_control, RTC_CONTROL);
324 	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
325 
326 	spin_unlock_irqrestore(&rtc_lock, flags);
327 
328 	return 0;
329 }
330 EXPORT_SYMBOL_GPL(mc146818_set_time);
331