Skip to content

Commit 2a61b0a

Browse files
matjonalexandrebelloni
authored andcommitted
rtc: mc146818-lib: refactor mc146818_get_time
Refactor mc146818_get_time() so that it uses mc146818_avoid_UIP(). Signed-off-by: Mateusz Jończyk <mat.jonczyk@o2.pl> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Link: https://lore.kernel.org/r/20211210200131.153887-7-mat.jonczyk@o2.pl
1 parent ec5895c commit 2a61b0a

1 file changed

Lines changed: 42 additions & 67 deletions

File tree

drivers/rtc/rtc-mc146818-lib.c

Lines changed: 42 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -103,105 +103,80 @@ bool mc146818_does_rtc_work(void)
103103
}
104104
EXPORT_SYMBOL_GPL(mc146818_does_rtc_work);
105105

106-
unsigned int mc146818_get_time(struct rtc_time *time)
107-
{
106+
struct mc146818_get_time_callback_param {
107+
struct rtc_time *time;
108108
unsigned char ctrl;
109-
unsigned long flags;
110-
unsigned int iter_count = 0;
111-
unsigned char century = 0;
112-
bool retry;
113-
109+
#ifdef CONFIG_ACPI
110+
unsigned char century;
111+
#endif
114112
#ifdef CONFIG_MACH_DECSTATION
115113
unsigned int real_year;
116114
#endif
115+
};
117116

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-
}
117+
static void mc146818_get_time_callback(unsigned char seconds, void *param_in)
118+
{
119+
struct mc146818_get_time_callback_param *p = param_in;
149120

150121
/*
151122
* Only the values that we read from the RTC are set. We leave
152123
* tm_wday, tm_yday and tm_isdst untouched. Even though the
153124
* RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
154125
* by the RTC when initially set to a non-zero value.
155126
*/
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);
127+
p->time->tm_sec = seconds;
128+
p->time->tm_min = CMOS_READ(RTC_MINUTES);
129+
p->time->tm_hour = CMOS_READ(RTC_HOURS);
130+
p->time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
131+
p->time->tm_mon = CMOS_READ(RTC_MONTH);
132+
p->time->tm_year = CMOS_READ(RTC_YEAR);
161133
#ifdef CONFIG_MACH_DECSTATION
162-
real_year = CMOS_READ(RTC_DEC_YEAR);
134+
p->real_year = CMOS_READ(RTC_DEC_YEAR);
163135
#endif
164136
#ifdef CONFIG_ACPI
165137
if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
166-
acpi_gbl_FADT.century)
167-
century = CMOS_READ(acpi_gbl_FADT.century);
138+
acpi_gbl_FADT.century) {
139+
p->century = CMOS_READ(acpi_gbl_FADT.century);
140+
} else {
141+
p->century = 0;
142+
}
168143
#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);
182144

183-
spin_unlock_irqrestore(&rtc_lock, flags);
145+
p->ctrl = CMOS_READ(RTC_CONTROL);
146+
}
184147

185-
if (retry)
186-
goto again;
148+
unsigned int mc146818_get_time(struct rtc_time *time)
149+
{
150+
struct mc146818_get_time_callback_param p = {
151+
.time = time
152+
};
153+
154+
if (!mc146818_avoid_UIP(mc146818_get_time_callback, &p)) {
155+
memset(time, 0, sizeof(*time));
156+
return -EIO;
157+
}
187158

188-
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
159+
if (!(p.ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
189160
{
190161
time->tm_sec = bcd2bin(time->tm_sec);
191162
time->tm_min = bcd2bin(time->tm_min);
192163
time->tm_hour = bcd2bin(time->tm_hour);
193164
time->tm_mday = bcd2bin(time->tm_mday);
194165
time->tm_mon = bcd2bin(time->tm_mon);
195166
time->tm_year = bcd2bin(time->tm_year);
196-
century = bcd2bin(century);
167+
#ifdef CONFIG_ACPI
168+
p.century = bcd2bin(p.century);
169+
#endif
197170
}
198171

199172
#ifdef CONFIG_MACH_DECSTATION
200-
time->tm_year += real_year - 72;
173+
time->tm_year += p.real_year - 72;
201174
#endif
202175

203-
if (century > 20)
204-
time->tm_year += (century - 19) * 100;
176+
#ifdef CONFIG_ACPI
177+
if (p.century > 20)
178+
time->tm_year += (p.century - 19) * 100;
179+
#endif
205180

206181
/*
207182
* Account for differences between how the RTC uses the values

0 commit comments

Comments
 (0)