Commit 3c217e51 authored by Sylvain Chouleur's avatar Sylvain Chouleur Committed by Alexandre Belloni

rtc: cmos: century support

If century field is supported by the RTC CMOS device, then we should use
it and then do not consider years greater that 169 as an error.

For information, the year field of the rtc_time structure contains the
value to add to 1970 to obtain the current year.

This was a hack to be able to support years for 1970 to 2069.
This patch remains compatible with this implementation.
Signed-off-by: default avatarSylvain Chouleur <sylvain.chouleur@intel.com>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
parent 11f67a8b
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/delay.h> #include <linux/delay.h>
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
#endif
#define RTC_PIE 0x40 /* periodic interrupt enable */ #define RTC_PIE 0x40 /* periodic interrupt enable */
#define RTC_AIE 0x20 /* alarm interrupt enable */ #define RTC_AIE 0x20 /* alarm interrupt enable */
...@@ -46,6 +49,7 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) ...@@ -46,6 +49,7 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time)
{ {
unsigned char ctrl; unsigned char ctrl;
unsigned long flags; unsigned long flags;
unsigned char century = 0;
#ifdef CONFIG_MACH_DECSTATION #ifdef CONFIG_MACH_DECSTATION
unsigned int real_year; unsigned int real_year;
...@@ -78,6 +82,11 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) ...@@ -78,6 +82,11 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time)
time->tm_year = CMOS_READ(RTC_YEAR); time->tm_year = CMOS_READ(RTC_YEAR);
#ifdef CONFIG_MACH_DECSTATION #ifdef CONFIG_MACH_DECSTATION
real_year = CMOS_READ(RTC_DEC_YEAR); real_year = CMOS_READ(RTC_DEC_YEAR);
#endif
#ifdef CONFIG_ACPI
if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
acpi_gbl_FADT.century)
century = CMOS_READ(acpi_gbl_FADT.century);
#endif #endif
ctrl = CMOS_READ(RTC_CONTROL); ctrl = CMOS_READ(RTC_CONTROL);
spin_unlock_irqrestore(&rtc_lock, flags); spin_unlock_irqrestore(&rtc_lock, flags);
...@@ -90,12 +99,16 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time) ...@@ -90,12 +99,16 @@ static inline unsigned int __get_rtc_time(struct rtc_time *time)
time->tm_mday = bcd2bin(time->tm_mday); time->tm_mday = bcd2bin(time->tm_mday);
time->tm_mon = bcd2bin(time->tm_mon); time->tm_mon = bcd2bin(time->tm_mon);
time->tm_year = bcd2bin(time->tm_year); time->tm_year = bcd2bin(time->tm_year);
century = bcd2bin(century);
} }
#ifdef CONFIG_MACH_DECSTATION #ifdef CONFIG_MACH_DECSTATION
time->tm_year += real_year - 72; time->tm_year += real_year - 72;
#endif #endif
if (century)
time->tm_year += (century - 19) * 100;
/* /*
* Account for differences between how the RTC uses the values * Account for differences between how the RTC uses the values
* and how they are defined in a struct rtc_time; * and how they are defined in a struct rtc_time;
...@@ -122,6 +135,7 @@ static inline int __set_rtc_time(struct rtc_time *time) ...@@ -122,6 +135,7 @@ static inline int __set_rtc_time(struct rtc_time *time)
#ifdef CONFIG_MACH_DECSTATION #ifdef CONFIG_MACH_DECSTATION
unsigned int real_yrs, leap_yr; unsigned int real_yrs, leap_yr;
#endif #endif
unsigned char century = 0;
yrs = time->tm_year; yrs = time->tm_year;
mon = time->tm_mon + 1; /* tm_mon starts at zero */ mon = time->tm_mon + 1; /* tm_mon starts at zero */
...@@ -150,6 +164,15 @@ static inline int __set_rtc_time(struct rtc_time *time) ...@@ -150,6 +164,15 @@ static inline int __set_rtc_time(struct rtc_time *time)
yrs = 73; yrs = 73;
} }
#endif #endif
#ifdef CONFIG_ACPI
if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
acpi_gbl_FADT.century) {
century = (yrs + 1900) / 100;
yrs %= 100;
}
#endif
/* These limits and adjustments are independent of /* These limits and adjustments are independent of
* whether the chip is in binary mode or not. * whether the chip is in binary mode or not.
*/ */
...@@ -169,6 +192,7 @@ static inline int __set_rtc_time(struct rtc_time *time) ...@@ -169,6 +192,7 @@ static inline int __set_rtc_time(struct rtc_time *time)
day = bin2bcd(day); day = bin2bcd(day);
mon = bin2bcd(mon); mon = bin2bcd(mon);
yrs = bin2bcd(yrs); yrs = bin2bcd(yrs);
century = bin2bcd(century);
} }
save_control = CMOS_READ(RTC_CONTROL); save_control = CMOS_READ(RTC_CONTROL);
...@@ -185,6 +209,11 @@ static inline int __set_rtc_time(struct rtc_time *time) ...@@ -185,6 +209,11 @@ static inline int __set_rtc_time(struct rtc_time *time)
CMOS_WRITE(hrs, RTC_HOURS); CMOS_WRITE(hrs, RTC_HOURS);
CMOS_WRITE(min, RTC_MINUTES); CMOS_WRITE(min, RTC_MINUTES);
CMOS_WRITE(sec, RTC_SECONDS); CMOS_WRITE(sec, RTC_SECONDS);
#ifdef CONFIG_ACPI
if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
acpi_gbl_FADT.century)
CMOS_WRITE(century, acpi_gbl_FADT.century);
#endif
CMOS_WRITE(save_control, RTC_CONTROL); CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment