1 #include <linux/bcd.h> 2 #include <linux/delay.h> 3 #include <linux/export.h> 4 #include <linux/mc146818rtc.h> 5 6 #ifdef CONFIG_ACPI 7 #include <linux/acpi.h> 8 #endif 9 10 /* 11 * Returns true if a clock update is in progress 12 */ 13 static inline unsigned char mc146818_is_updating(void) 14 { 15 unsigned char uip; 16 unsigned long flags; 17 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 } 23 24 unsigned int mc146818_get_time(struct rtc_time *time) 25 { 26 unsigned char ctrl; 27 unsigned long flags; 28 unsigned char century = 0; 29 30 #ifdef CONFIG_MACH_DECSTATION 31 unsigned int real_year; 32 #endif 33 34 /* 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. 42 */ 43 if (mc146818_is_updating()) 44 mdelay(20); 45 46 /* 47 * Only the values that we read from the RTC are set. We leave 48 * tm_wday, tm_yday and tm_isdst untouched. Even though the 49 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated 50 * by the RTC when initially set to a non-zero value. 51 */ 52 spin_lock_irqsave(&rtc_lock, flags); 53 time->tm_sec = CMOS_READ(RTC_SECONDS); 54 time->tm_min = CMOS_READ(RTC_MINUTES); 55 time->tm_hour = CMOS_READ(RTC_HOURS); 56 time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH); 57 time->tm_mon = CMOS_READ(RTC_MONTH); 58 time->tm_year = CMOS_READ(RTC_YEAR); 59 #ifdef CONFIG_MACH_DECSTATION 60 real_year = CMOS_READ(RTC_DEC_YEAR); 61 #endif 62 #ifdef CONFIG_ACPI 63 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && 64 acpi_gbl_FADT.century) 65 century = CMOS_READ(acpi_gbl_FADT.century); 66 #endif 67 ctrl = CMOS_READ(RTC_CONTROL); 68 spin_unlock_irqrestore(&rtc_lock, flags); 69 70 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 71 { 72 time->tm_sec = bcd2bin(time->tm_sec); 73 time->tm_min = bcd2bin(time->tm_min); 74 time->tm_hour = bcd2bin(time->tm_hour); 75 time->tm_mday = bcd2bin(time->tm_mday); 76 time->tm_mon = bcd2bin(time->tm_mon); 77 time->tm_year = bcd2bin(time->tm_year); 78 century = bcd2bin(century); 79 } 80 81 #ifdef CONFIG_MACH_DECSTATION 82 time->tm_year += real_year - 72; 83 #endif 84 85 if (century > 20) 86 time->tm_year += (century - 19) * 100; 87 88 /* 89 * Account for differences between how the RTC uses the values 90 * and how they are defined in a struct rtc_time; 91 */ 92 if (time->tm_year <= 69) 93 time->tm_year += 100; 94 95 time->tm_mon--; 96 97 return RTC_24H; 98 } 99 EXPORT_SYMBOL_GPL(mc146818_get_time); 100 101 /* Set the current date and time in the real time clock. */ 102 int mc146818_set_time(struct rtc_time *time) 103 { 104 unsigned long flags; 105 unsigned char mon, day, hrs, min, sec; 106 unsigned char save_control, save_freq_select; 107 unsigned int yrs; 108 #ifdef CONFIG_MACH_DECSTATION 109 unsigned int real_yrs, leap_yr; 110 #endif 111 unsigned char century = 0; 112 113 yrs = time->tm_year; 114 mon = time->tm_mon + 1; /* tm_mon starts at zero */ 115 day = time->tm_mday; 116 hrs = time->tm_hour; 117 min = time->tm_min; 118 sec = time->tm_sec; 119 120 if (yrs > 255) /* They are unsigned */ 121 return -EINVAL; 122 123 spin_lock_irqsave(&rtc_lock, flags); 124 #ifdef CONFIG_MACH_DECSTATION 125 real_yrs = yrs; 126 leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) || 127 !((yrs + 1900) % 400)); 128 yrs = 72; 129 130 /* 131 * We want to keep the year set to 73 until March 132 * for non-leap years, so that Feb, 29th is handled 133 * correctly. 134 */ 135 if (!leap_yr && mon < 3) { 136 real_yrs--; 137 yrs = 73; 138 } 139 #endif 140 141 #ifdef CONFIG_ACPI 142 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && 143 acpi_gbl_FADT.century) { 144 century = (yrs + 1900) / 100; 145 yrs %= 100; 146 } 147 #endif 148 149 /* These limits and adjustments are independent of 150 * whether the chip is in binary mode or not. 151 */ 152 if (yrs > 169) { 153 spin_unlock_irqrestore(&rtc_lock, flags); 154 return -EINVAL; 155 } 156 157 if (yrs >= 100) 158 yrs -= 100; 159 160 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) 161 || RTC_ALWAYS_BCD) { 162 sec = bin2bcd(sec); 163 min = bin2bcd(min); 164 hrs = bin2bcd(hrs); 165 day = bin2bcd(day); 166 mon = bin2bcd(mon); 167 yrs = bin2bcd(yrs); 168 century = bin2bcd(century); 169 } 170 171 save_control = CMOS_READ(RTC_CONTROL); 172 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); 173 save_freq_select = CMOS_READ(RTC_FREQ_SELECT); 174 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 175 176 #ifdef CONFIG_MACH_DECSTATION 177 CMOS_WRITE(real_yrs, RTC_DEC_YEAR); 178 #endif 179 CMOS_WRITE(yrs, RTC_YEAR); 180 CMOS_WRITE(mon, RTC_MONTH); 181 CMOS_WRITE(day, RTC_DAY_OF_MONTH); 182 CMOS_WRITE(hrs, RTC_HOURS); 183 CMOS_WRITE(min, RTC_MINUTES); 184 CMOS_WRITE(sec, RTC_SECONDS); 185 #ifdef CONFIG_ACPI 186 if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && 187 acpi_gbl_FADT.century) 188 CMOS_WRITE(century, acpi_gbl_FADT.century); 189 #endif 190 191 CMOS_WRITE(save_control, RTC_CONTROL); 192 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 193 194 spin_unlock_irqrestore(&rtc_lock, flags); 195 196 return 0; 197 } 198 EXPORT_SYMBOL_GPL(mc146818_set_time); 199