@@ -103,105 +103,80 @@ bool mc146818_does_rtc_work(void)
103103}
104104EXPORT_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