hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/rtc/rtc-mc146818-lib.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/bcd.h>
23 #include <linux/delay.h>
34 #include <linux/export.h>
....@@ -8,40 +9,143 @@
89 #endif
910
1011 /*
11
- * Returns true if a clock update is in progress
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.
1216 */
13
-static inline unsigned char mc146818_is_updating(void)
17
+bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
18
+ void *param)
1419 {
15
- unsigned char uip;
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
+ */
85
+bool mc146818_does_rtc_work(void)
86
+{
87
+ int i;
88
+ unsigned char val;
1689 unsigned long flags;
1790
18
- spin_lock_irqsave(&rtc_lock, flags);
19
- uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
20
- spin_unlock_irqrestore(&rtc_lock, flags);
21
- return uip;
22
-}
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);
2395
24
-unsigned int mc146818_get_time(struct rtc_time *time)
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
+
106
+int mc146818_get_time(struct rtc_time *time)
25107 {
26108 unsigned char ctrl;
27109 unsigned long flags;
110
+ unsigned int iter_count = 0;
28111 unsigned char century = 0;
112
+ bool retry;
29113
30114 #ifdef CONFIG_MACH_DECSTATION
31115 unsigned int real_year;
32116 #endif
33117
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
+
34127 /*
35
- * read RTC once any update in progress is done. The update
36
- * can take just over 2ms. We wait 20ms. There is no need to
37
- * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
38
- * If you need to know *exactly* when a second has started, enable
39
- * periodic update complete interrupts, (via ioctl) and then
40
- * immediately read /dev/rtc which will block until you get the IRQ.
41
- * Once the read clears, read the RTC time (again via ioctl). Easy.
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.
42135 */
43
- if (mc146818_is_updating())
44
- mdelay(20);
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
+ }
45149
46150 /*
47151 * Only the values that we read from the RTC are set. We leave
....@@ -49,8 +153,6 @@
49153 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
50154 * by the RTC when initially set to a non-zero value.
51155 */
52
- spin_lock_irqsave(&rtc_lock, flags);
53
- time->tm_sec = CMOS_READ(RTC_SECONDS);
54156 time->tm_min = CMOS_READ(RTC_MINUTES);
55157 time->tm_hour = CMOS_READ(RTC_HOURS);
56158 time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
....@@ -65,7 +167,23 @@
65167 century = CMOS_READ(acpi_gbl_FADT.century);
66168 #endif
67169 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
+
68183 spin_unlock_irqrestore(&rtc_lock, flags);
184
+
185
+ if (retry)
186
+ goto again;
69187
70188 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
71189 {
....@@ -94,9 +212,20 @@
94212
95213 time->tm_mon--;
96214
97
- return RTC_24H;
215
+ return 0;
98216 }
99217 EXPORT_SYMBOL_GPL(mc146818_get_time);
218
+
219
+/* AMD systems don't allow access to AltCentury with DV1 */
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
+}
100229
101230 /* Set the current date and time in the real time clock. */
102231 int mc146818_set_time(struct rtc_time *time)
....@@ -120,7 +249,6 @@
120249 if (yrs > 255) /* They are unsigned */
121250 return -EINVAL;
122251
123
- spin_lock_irqsave(&rtc_lock, flags);
124252 #ifdef CONFIG_MACH_DECSTATION
125253 real_yrs = yrs;
126254 leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
....@@ -149,16 +277,16 @@
149277 /* These limits and adjustments are independent of
150278 * whether the chip is in binary mode or not.
151279 */
152
- if (yrs > 169) {
153
- spin_unlock_irqrestore(&rtc_lock, flags);
280
+ if (yrs > 169)
154281 return -EINVAL;
155
- }
156282
157283 if (yrs >= 100)
158284 yrs -= 100;
159285
160
- if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
161
- || RTC_ALWAYS_BCD) {
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) {
162290 sec = bin2bcd(sec);
163291 min = bin2bcd(min);
164292 hrs = bin2bcd(hrs);
....@@ -168,10 +296,14 @@
168296 century = bin2bcd(century);
169297 }
170298
299
+ spin_lock_irqsave(&rtc_lock, flags);
171300 save_control = CMOS_READ(RTC_CONTROL);
172301 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
173302 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
174
- CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), 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);
175307
176308 #ifdef CONFIG_MACH_DECSTATION
177309 CMOS_WRITE(real_yrs, RTC_DEC_YEAR);