Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 #include <linux/bcd.h>
0003 #include <linux/delay.h>
0004 #include <linux/export.h>
0005 #include <linux/mc146818rtc.h>
0006 
0007 #ifdef CONFIG_ACPI
0008 #include <linux/acpi.h>
0009 #endif
0010 
0011 /*
0012  * Execute a function while the UIP (Update-in-progress) bit of the RTC is
0013  * unset.
0014  *
0015  * Warning: callback may be executed more then once.
0016  */
0017 bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
0018             void *param)
0019 {
0020     int i;
0021     unsigned long flags;
0022     unsigned char seconds;
0023 
0024     for (i = 0; i < 100; i++) {
0025         spin_lock_irqsave(&rtc_lock, flags);
0026 
0027         /*
0028          * Check whether there is an update in progress during which the
0029          * readout is unspecified. The maximum update time is ~2ms. Poll
0030          * every 100 usec for completion.
0031          *
0032          * Store the second value before checking UIP so a long lasting
0033          * NMI which happens to hit after the UIP check cannot make
0034          * an update cycle invisible.
0035          */
0036         seconds = CMOS_READ(RTC_SECONDS);
0037 
0038         if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
0039             spin_unlock_irqrestore(&rtc_lock, flags);
0040             udelay(100);
0041             continue;
0042         }
0043 
0044         /* Revalidate the above readout */
0045         if (seconds != CMOS_READ(RTC_SECONDS)) {
0046             spin_unlock_irqrestore(&rtc_lock, flags);
0047             continue;
0048         }
0049 
0050         if (callback)
0051             callback(seconds, param);
0052 
0053         /*
0054          * Check for the UIP bit again. If it is set now then
0055          * the above values may contain garbage.
0056          */
0057         if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
0058             spin_unlock_irqrestore(&rtc_lock, flags);
0059             udelay(100);
0060             continue;
0061         }
0062 
0063         /*
0064          * A NMI might have interrupted the above sequence so check
0065          * whether the seconds value has changed which indicates that
0066          * the NMI took longer than the UIP bit was set. Unlikely, but
0067          * possible and there is also virt...
0068          */
0069         if (seconds != CMOS_READ(RTC_SECONDS)) {
0070             spin_unlock_irqrestore(&rtc_lock, flags);
0071             continue;
0072         }
0073         spin_unlock_irqrestore(&rtc_lock, flags);
0074 
0075         return true;
0076     }
0077     return false;
0078 }
0079 EXPORT_SYMBOL_GPL(mc146818_avoid_UIP);
0080 
0081 /*
0082  * If the UIP (Update-in-progress) bit of the RTC is set for more then
0083  * 10ms, the RTC is apparently broken or not present.
0084  */
0085 bool mc146818_does_rtc_work(void)
0086 {
0087     return mc146818_avoid_UIP(NULL, NULL);
0088 }
0089 EXPORT_SYMBOL_GPL(mc146818_does_rtc_work);
0090 
0091 struct mc146818_get_time_callback_param {
0092     struct rtc_time *time;
0093     unsigned char ctrl;
0094 #ifdef CONFIG_ACPI
0095     unsigned char century;
0096 #endif
0097 #ifdef CONFIG_MACH_DECSTATION
0098     unsigned int real_year;
0099 #endif
0100 };
0101 
0102 static void mc146818_get_time_callback(unsigned char seconds, void *param_in)
0103 {
0104     struct mc146818_get_time_callback_param *p = param_in;
0105 
0106     /*
0107      * Only the values that we read from the RTC are set. We leave
0108      * tm_wday, tm_yday and tm_isdst untouched. Even though the
0109      * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
0110      * by the RTC when initially set to a non-zero value.
0111      */
0112     p->time->tm_sec = seconds;
0113     p->time->tm_min = CMOS_READ(RTC_MINUTES);
0114     p->time->tm_hour = CMOS_READ(RTC_HOURS);
0115     p->time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
0116     p->time->tm_mon = CMOS_READ(RTC_MONTH);
0117     p->time->tm_year = CMOS_READ(RTC_YEAR);
0118 #ifdef CONFIG_MACH_DECSTATION
0119     p->real_year = CMOS_READ(RTC_DEC_YEAR);
0120 #endif
0121 #ifdef CONFIG_ACPI
0122     if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
0123         acpi_gbl_FADT.century) {
0124         p->century = CMOS_READ(acpi_gbl_FADT.century);
0125     } else {
0126         p->century = 0;
0127     }
0128 #endif
0129 
0130     p->ctrl = CMOS_READ(RTC_CONTROL);
0131 }
0132 
0133 int mc146818_get_time(struct rtc_time *time)
0134 {
0135     struct mc146818_get_time_callback_param p = {
0136         .time = time
0137     };
0138 
0139     if (!mc146818_avoid_UIP(mc146818_get_time_callback, &p)) {
0140         memset(time, 0, sizeof(*time));
0141         return -EIO;
0142     }
0143 
0144     if (!(p.ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
0145     {
0146         time->tm_sec = bcd2bin(time->tm_sec);
0147         time->tm_min = bcd2bin(time->tm_min);
0148         time->tm_hour = bcd2bin(time->tm_hour);
0149         time->tm_mday = bcd2bin(time->tm_mday);
0150         time->tm_mon = bcd2bin(time->tm_mon);
0151         time->tm_year = bcd2bin(time->tm_year);
0152 #ifdef CONFIG_ACPI
0153         p.century = bcd2bin(p.century);
0154 #endif
0155     }
0156 
0157 #ifdef CONFIG_MACH_DECSTATION
0158     time->tm_year += p.real_year - 72;
0159 #endif
0160 
0161 #ifdef CONFIG_ACPI
0162     if (p.century > 19)
0163         time->tm_year += (p.century - 19) * 100;
0164 #endif
0165 
0166     /*
0167      * Account for differences between how the RTC uses the values
0168      * and how they are defined in a struct rtc_time;
0169      */
0170     if (time->tm_year <= 69)
0171         time->tm_year += 100;
0172 
0173     time->tm_mon--;
0174 
0175     return 0;
0176 }
0177 EXPORT_SYMBOL_GPL(mc146818_get_time);
0178 
0179 /* AMD systems don't allow access to AltCentury with DV1 */
0180 static bool apply_amd_register_a_behavior(void)
0181 {
0182 #ifdef CONFIG_X86
0183     if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
0184         boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
0185         return true;
0186 #endif
0187     return false;
0188 }
0189 
0190 /* Set the current date and time in the real time clock. */
0191 int mc146818_set_time(struct rtc_time *time)
0192 {
0193     unsigned long flags;
0194     unsigned char mon, day, hrs, min, sec;
0195     unsigned char save_control, save_freq_select;
0196     unsigned int yrs;
0197 #ifdef CONFIG_MACH_DECSTATION
0198     unsigned int real_yrs, leap_yr;
0199 #endif
0200     unsigned char century = 0;
0201 
0202     yrs = time->tm_year;
0203     mon = time->tm_mon + 1;   /* tm_mon starts at zero */
0204     day = time->tm_mday;
0205     hrs = time->tm_hour;
0206     min = time->tm_min;
0207     sec = time->tm_sec;
0208 
0209     if (yrs > 255)  /* They are unsigned */
0210         return -EINVAL;
0211 
0212 #ifdef CONFIG_MACH_DECSTATION
0213     real_yrs = yrs;
0214     leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
0215             !((yrs + 1900) % 400));
0216     yrs = 72;
0217 
0218     /*
0219      * We want to keep the year set to 73 until March
0220      * for non-leap years, so that Feb, 29th is handled
0221      * correctly.
0222      */
0223     if (!leap_yr && mon < 3) {
0224         real_yrs--;
0225         yrs = 73;
0226     }
0227 #endif
0228 
0229 #ifdef CONFIG_ACPI
0230     if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
0231         acpi_gbl_FADT.century) {
0232         century = (yrs + 1900) / 100;
0233         yrs %= 100;
0234     }
0235 #endif
0236 
0237     /* These limits and adjustments are independent of
0238      * whether the chip is in binary mode or not.
0239      */
0240     if (yrs > 169)
0241         return -EINVAL;
0242 
0243     if (yrs >= 100)
0244         yrs -= 100;
0245 
0246     spin_lock_irqsave(&rtc_lock, flags);
0247     save_control = CMOS_READ(RTC_CONTROL);
0248     spin_unlock_irqrestore(&rtc_lock, flags);
0249     if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
0250         sec = bin2bcd(sec);
0251         min = bin2bcd(min);
0252         hrs = bin2bcd(hrs);
0253         day = bin2bcd(day);
0254         mon = bin2bcd(mon);
0255         yrs = bin2bcd(yrs);
0256         century = bin2bcd(century);
0257     }
0258 
0259     spin_lock_irqsave(&rtc_lock, flags);
0260     save_control = CMOS_READ(RTC_CONTROL);
0261     CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
0262     save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
0263     if (apply_amd_register_a_behavior())
0264         CMOS_WRITE((save_freq_select & ~RTC_AMD_BANK_SELECT), RTC_FREQ_SELECT);
0265     else
0266         CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
0267 
0268 #ifdef CONFIG_MACH_DECSTATION
0269     CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
0270 #endif
0271     CMOS_WRITE(yrs, RTC_YEAR);
0272     CMOS_WRITE(mon, RTC_MONTH);
0273     CMOS_WRITE(day, RTC_DAY_OF_MONTH);
0274     CMOS_WRITE(hrs, RTC_HOURS);
0275     CMOS_WRITE(min, RTC_MINUTES);
0276     CMOS_WRITE(sec, RTC_SECONDS);
0277 #ifdef CONFIG_ACPI
0278     if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
0279         acpi_gbl_FADT.century)
0280         CMOS_WRITE(century, acpi_gbl_FADT.century);
0281 #endif
0282 
0283     CMOS_WRITE(save_control, RTC_CONTROL);
0284     CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
0285 
0286     spin_unlock_irqrestore(&rtc_lock, flags);
0287 
0288     return 0;
0289 }
0290 EXPORT_SYMBOL_GPL(mc146818_set_time);