aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2011-11-10 08:23:39 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-11 20:58:58 -0500
commit57e6319dd61d5ca10fe8dd57bcce8c0e2c480799 (patch)
tree906c40cec199f96f657a1e782fdc4dfcfdc81ade /drivers/rtc
parentf2ee442115c9b6219083c019939a9cc0c9abb2f8 (diff)
vrtc: change its year offset from 1960 to 1972
Real world year equals the value in vrtc YEAR register plus an offset. We used 1960 as the offset to make leap year consistent, but for a device's first use, its YEAR register is 0 and the system year will be parsed as 1960 which is not a valid UNIX time and will cause many applications to fail mysteriously. So we use 1972 instead to fix this issue. Updated patch which adds a sanity check suggested by Mathias This isn't a change in behaviour for systems, because 1972 is the one we actually use. It's the old version in upstream which is out of sync with all devices. Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-mrst.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index d33544802a2..bb21f443fb7 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -76,12 +76,15 @@ static inline unsigned char vrtc_is_updating(void)
76/* 76/*
77 * rtc_time's year contains the increment over 1900, but vRTC's YEAR 77 * rtc_time's year contains the increment over 1900, but vRTC's YEAR
78 * register can't be programmed to value larger than 0x64, so vRTC 78 * register can't be programmed to value larger than 0x64, so vRTC
79 * driver chose to use 1960 (1970 is UNIX time start point) as the base, 79 * driver chose to use 1972 (1970 is UNIX time start point) as the base,
80 * and does the translation at read/write time. 80 * and does the translation at read/write time.
81 * 81 *
82 * Why not just use 1970 as the offset? it's because using 1960 will 82 * Why not just use 1970 as the offset? it's because using 1972 will
83 * make it consistent in leap year setting for both vrtc and low-level 83 * make it consistent in leap year setting for both vrtc and low-level
84 * physical rtc devices. 84 * physical rtc devices. Then why not use 1960 as the offset? If we use
85 * 1960, for a device's first use, its YEAR register is 0 and the system
86 * year will be parsed as 1960 which is not a valid UNIX time and will
87 * cause many applications to fail mysteriously.
85 */ 88 */
86static int mrst_read_time(struct device *dev, struct rtc_time *time) 89static int mrst_read_time(struct device *dev, struct rtc_time *time)
87{ 90{
@@ -99,10 +102,10 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
99 time->tm_year = vrtc_cmos_read(RTC_YEAR); 102 time->tm_year = vrtc_cmos_read(RTC_YEAR);
100 spin_unlock_irqrestore(&rtc_lock, flags); 103 spin_unlock_irqrestore(&rtc_lock, flags);
101 104
102 /* Adjust for the 1960/1900 */ 105 /* Adjust for the 1972/1900 */
103 time->tm_year += 60; 106 time->tm_year += 72;
104 time->tm_mon--; 107 time->tm_mon--;
105 return RTC_24H; 108 return rtc_valid_tm(time);
106} 109}
107 110
108static int mrst_set_time(struct device *dev, struct rtc_time *time) 111static int mrst_set_time(struct device *dev, struct rtc_time *time)
@@ -119,9 +122,9 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time)
119 min = time->tm_min; 122 min = time->tm_min;
120 sec = time->tm_sec; 123 sec = time->tm_sec;
121 124
122 if (yrs < 70 || yrs > 138) 125 if (yrs < 72 || yrs > 138)
123 return -EINVAL; 126 return -EINVAL;
124 yrs -= 60; 127 yrs -= 72;
125 128
126 spin_lock_irqsave(&rtc_lock, flags); 129 spin_lock_irqsave(&rtc_lock, flags);
127 130