diff options
| -rw-r--r-- | arch/x86/platform/mrst/vrtc.c | 4 | ||||
| -rw-r--r-- | drivers/rtc/rtc-mrst.c | 19 |
2 files changed, 13 insertions, 10 deletions
diff --git a/arch/x86/platform/mrst/vrtc.c b/arch/x86/platform/mrst/vrtc.c index a8ac6f1eb66d..225bd0f0f675 100644 --- a/arch/x86/platform/mrst/vrtc.c +++ b/arch/x86/platform/mrst/vrtc.c | |||
| @@ -76,8 +76,8 @@ unsigned long vrtc_get_time(void) | |||
| 76 | 76 | ||
| 77 | spin_unlock_irqrestore(&rtc_lock, flags); | 77 | spin_unlock_irqrestore(&rtc_lock, flags); |
| 78 | 78 | ||
| 79 | /* vRTC YEAR reg contains the offset to 1960 */ | 79 | /* vRTC YEAR reg contains the offset to 1972 */ |
| 80 | year += 1960; | 80 | year += 1972; |
| 81 | 81 | ||
| 82 | printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d " | 82 | printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d " |
| 83 | "mon: %d year: %d\n", sec, min, hour, mday, mon, year); | 83 | "mon: %d year: %d\n", sec, min, hour, mday, mon, year); |
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index d33544802a2e..bb21f443fb70 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 | */ |
| 86 | static int mrst_read_time(struct device *dev, struct rtc_time *time) | 89 | static 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 | ||
| 108 | static int mrst_set_time(struct device *dev, struct rtc_time *time) | 111 | static 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 | ||
