rtc-mc146818-lib.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/bcd.h>
  3. #include <linux/delay.h>
  4. #include <linux/export.h>
  5. #include <linux/mc146818rtc.h>
  6. #ifdef CONFIG_ACPI
  7. #include <linux/acpi.h>
  8. #endif
  9. /*
  10. * Execute a function while the UIP (Update-in-progress) bit of the RTC is
  11. * unset.
  12. *
  13. * Warning: callback may be executed more then once.
  14. */
  15. bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param),
  16. void *param)
  17. {
  18. int i;
  19. unsigned long flags;
  20. unsigned char seconds;
  21. for (i = 0; i < 100; i++) {
  22. spin_lock_irqsave(&rtc_lock, flags);
  23. /*
  24. * Check whether there is an update in progress during which the
  25. * readout is unspecified. The maximum update time is ~2ms. Poll
  26. * every 100 usec for completion.
  27. *
  28. * Store the second value before checking UIP so a long lasting
  29. * NMI which happens to hit after the UIP check cannot make
  30. * an update cycle invisible.
  31. */
  32. seconds = CMOS_READ(RTC_SECONDS);
  33. if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
  34. spin_unlock_irqrestore(&rtc_lock, flags);
  35. udelay(100);
  36. continue;
  37. }
  38. /* Revalidate the above readout */
  39. if (seconds != CMOS_READ(RTC_SECONDS)) {
  40. spin_unlock_irqrestore(&rtc_lock, flags);
  41. continue;
  42. }
  43. if (callback)
  44. callback(seconds, param);
  45. /*
  46. * Check for the UIP bit again. If it is set now then
  47. * the above values may contain garbage.
  48. */
  49. if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) {
  50. spin_unlock_irqrestore(&rtc_lock, flags);
  51. udelay(100);
  52. continue;
  53. }
  54. /*
  55. * A NMI might have interrupted the above sequence so check
  56. * whether the seconds value has changed which indicates that
  57. * the NMI took longer than the UIP bit was set. Unlikely, but
  58. * possible and there is also virt...
  59. */
  60. if (seconds != CMOS_READ(RTC_SECONDS)) {
  61. spin_unlock_irqrestore(&rtc_lock, flags);
  62. continue;
  63. }
  64. spin_unlock_irqrestore(&rtc_lock, flags);
  65. return true;
  66. }
  67. return false;
  68. }
  69. EXPORT_SYMBOL_GPL(mc146818_avoid_UIP);
  70. /*
  71. * If the UIP (Update-in-progress) bit of the RTC is set for more then
  72. * 10ms, the RTC is apparently broken or not present.
  73. */
  74. bool mc146818_does_rtc_work(void)
  75. {
  76. return mc146818_avoid_UIP(NULL, NULL);
  77. }
  78. EXPORT_SYMBOL_GPL(mc146818_does_rtc_work);
  79. struct mc146818_get_time_callback_param {
  80. struct rtc_time *time;
  81. unsigned char ctrl;
  82. #ifdef CONFIG_ACPI
  83. unsigned char century;
  84. #endif
  85. #ifdef CONFIG_MACH_DECSTATION
  86. unsigned int real_year;
  87. #endif
  88. };
  89. static void mc146818_get_time_callback(unsigned char seconds, void *param_in)
  90. {
  91. struct mc146818_get_time_callback_param *p = param_in;
  92. /*
  93. * Only the values that we read from the RTC are set. We leave
  94. * tm_wday, tm_yday and tm_isdst untouched. Even though the
  95. * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
  96. * by the RTC when initially set to a non-zero value.
  97. */
  98. p->time->tm_sec = seconds;
  99. p->time->tm_min = CMOS_READ(RTC_MINUTES);
  100. p->time->tm_hour = CMOS_READ(RTC_HOURS);
  101. p->time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
  102. p->time->tm_mon = CMOS_READ(RTC_MONTH);
  103. p->time->tm_year = CMOS_READ(RTC_YEAR);
  104. #ifdef CONFIG_MACH_DECSTATION
  105. p->real_year = CMOS_READ(RTC_DEC_YEAR);
  106. #endif
  107. #ifdef CONFIG_ACPI
  108. if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
  109. acpi_gbl_FADT.century) {
  110. p->century = CMOS_READ(acpi_gbl_FADT.century);
  111. } else {
  112. p->century = 0;
  113. }
  114. #endif
  115. p->ctrl = CMOS_READ(RTC_CONTROL);
  116. }
  117. int mc146818_get_time(struct rtc_time *time)
  118. {
  119. struct mc146818_get_time_callback_param p = {
  120. .time = time
  121. };
  122. if (!mc146818_avoid_UIP(mc146818_get_time_callback, &p)) {
  123. memset(time, 0, sizeof(*time));
  124. return -EIO;
  125. }
  126. if (!(p.ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
  127. {
  128. time->tm_sec = bcd2bin(time->tm_sec);
  129. time->tm_min = bcd2bin(time->tm_min);
  130. time->tm_hour = bcd2bin(time->tm_hour);
  131. time->tm_mday = bcd2bin(time->tm_mday);
  132. time->tm_mon = bcd2bin(time->tm_mon);
  133. time->tm_year = bcd2bin(time->tm_year);
  134. #ifdef CONFIG_ACPI
  135. p.century = bcd2bin(p.century);
  136. #endif
  137. }
  138. #ifdef CONFIG_MACH_DECSTATION
  139. time->tm_year += p.real_year - 72;
  140. #endif
  141. #ifdef CONFIG_ACPI
  142. if (p.century > 19)
  143. time->tm_year += (p.century - 19) * 100;
  144. #endif
  145. /*
  146. * Account for differences between how the RTC uses the values
  147. * and how they are defined in a struct rtc_time;
  148. */
  149. if (time->tm_year <= 69)
  150. time->tm_year += 100;
  151. time->tm_mon--;
  152. return 0;
  153. }
  154. EXPORT_SYMBOL_GPL(mc146818_get_time);
  155. /* AMD systems don't allow access to AltCentury with DV1 */
  156. static bool apply_amd_register_a_behavior(void)
  157. {
  158. #ifdef CONFIG_X86
  159. if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
  160. boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
  161. return true;
  162. #endif
  163. return false;
  164. }
  165. /* Set the current date and time in the real time clock. */
  166. int mc146818_set_time(struct rtc_time *time)
  167. {
  168. unsigned long flags;
  169. unsigned char mon, day, hrs, min, sec;
  170. unsigned char save_control, save_freq_select;
  171. unsigned int yrs;
  172. #ifdef CONFIG_MACH_DECSTATION
  173. unsigned int real_yrs, leap_yr;
  174. #endif
  175. unsigned char century = 0;
  176. yrs = time->tm_year;
  177. mon = time->tm_mon + 1; /* tm_mon starts at zero */
  178. day = time->tm_mday;
  179. hrs = time->tm_hour;
  180. min = time->tm_min;
  181. sec = time->tm_sec;
  182. if (yrs > 255) /* They are unsigned */
  183. return -EINVAL;
  184. #ifdef CONFIG_MACH_DECSTATION
  185. real_yrs = yrs;
  186. leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
  187. !((yrs + 1900) % 400));
  188. yrs = 72;
  189. /*
  190. * We want to keep the year set to 73 until March
  191. * for non-leap years, so that Feb, 29th is handled
  192. * correctly.
  193. */
  194. if (!leap_yr && mon < 3) {
  195. real_yrs--;
  196. yrs = 73;
  197. }
  198. #endif
  199. #ifdef CONFIG_ACPI
  200. if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
  201. acpi_gbl_FADT.century) {
  202. century = (yrs + 1900) / 100;
  203. yrs %= 100;
  204. }
  205. #endif
  206. /* These limits and adjustments are independent of
  207. * whether the chip is in binary mode or not.
  208. */
  209. if (yrs > 169)
  210. return -EINVAL;
  211. if (yrs >= 100)
  212. yrs -= 100;
  213. spin_lock_irqsave(&rtc_lock, flags);
  214. save_control = CMOS_READ(RTC_CONTROL);
  215. spin_unlock_irqrestore(&rtc_lock, flags);
  216. if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
  217. sec = bin2bcd(sec);
  218. min = bin2bcd(min);
  219. hrs = bin2bcd(hrs);
  220. day = bin2bcd(day);
  221. mon = bin2bcd(mon);
  222. yrs = bin2bcd(yrs);
  223. century = bin2bcd(century);
  224. }
  225. spin_lock_irqsave(&rtc_lock, flags);
  226. save_control = CMOS_READ(RTC_CONTROL);
  227. CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
  228. save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
  229. if (apply_amd_register_a_behavior())
  230. CMOS_WRITE((save_freq_select & ~RTC_AMD_BANK_SELECT), RTC_FREQ_SELECT);
  231. else
  232. CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
  233. #ifdef CONFIG_MACH_DECSTATION
  234. CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
  235. #endif
  236. CMOS_WRITE(yrs, RTC_YEAR);
  237. CMOS_WRITE(mon, RTC_MONTH);
  238. CMOS_WRITE(day, RTC_DAY_OF_MONTH);
  239. CMOS_WRITE(hrs, RTC_HOURS);
  240. CMOS_WRITE(min, RTC_MINUTES);
  241. CMOS_WRITE(sec, RTC_SECONDS);
  242. #ifdef CONFIG_ACPI
  243. if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
  244. acpi_gbl_FADT.century)
  245. CMOS_WRITE(century, acpi_gbl_FADT.century);
  246. #endif
  247. CMOS_WRITE(save_control, RTC_CONTROL);
  248. CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
  249. spin_unlock_irqrestore(&rtc_lock, flags);
  250. return 0;
  251. }
  252. EXPORT_SYMBOL_GPL(mc146818_set_time);