Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers/rtc/ab3100: Update driver to address y2038/y2106 issues

This driver has a number of y2038/y2106 issues.

This patch resolves them by:

- Replacing rtc_tm_to_time() with rtc_tm_to_time64()
- Replacing rtc_time_to_tm() with rtc_time64_to_tm()
- Changing ab3100_rtc_set_mmss() to use rtc_class_ops's set_mmss64()

After this patch, the driver should not have any remaining
y2038/y2106 issues.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-10-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Xunlei Pang and committed by
Ingo Molnar
5c7e11bc 4d644ab8

+27 -28
+27 -28
drivers/rtc/rtc-ab3100.c
··· 43 43 /* 44 44 * RTC clock functions and device struct declaration 45 45 */ 46 - static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) 46 + static int ab3100_rtc_set_mmss(struct device *dev, time64_t secs) 47 47 { 48 48 u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2, 49 49 AB3100_TI3, AB3100_TI4, AB3100_TI5}; 50 50 unsigned char buf[6]; 51 - u64 fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2; 51 + u64 hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2; 52 52 int err = 0; 53 53 int i; 54 54 55 - buf[0] = (fat_time) & 0xFF; 56 - buf[1] = (fat_time >> 8) & 0xFF; 57 - buf[2] = (fat_time >> 16) & 0xFF; 58 - buf[3] = (fat_time >> 24) & 0xFF; 59 - buf[4] = (fat_time >> 32) & 0xFF; 60 - buf[5] = (fat_time >> 40) & 0xFF; 55 + buf[0] = (hw_counter) & 0xFF; 56 + buf[1] = (hw_counter >> 8) & 0xFF; 57 + buf[2] = (hw_counter >> 16) & 0xFF; 58 + buf[3] = (hw_counter >> 24) & 0xFF; 59 + buf[4] = (hw_counter >> 32) & 0xFF; 60 + buf[5] = (hw_counter >> 40) & 0xFF; 61 61 62 62 for (i = 0; i < 6; i++) { 63 63 err = abx500_set_register_interruptible(dev, 0, ··· 75 75 76 76 static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) 77 77 { 78 - unsigned long time; 78 + time64_t time; 79 79 u8 rtcval; 80 80 int err; 81 81 ··· 88 88 dev_info(dev, "clock not set (lost power)"); 89 89 return -EINVAL; 90 90 } else { 91 - u64 fat_time; 91 + u64 hw_counter; 92 92 u8 buf[6]; 93 93 94 94 /* Read out time registers */ ··· 98 98 if (err != 0) 99 99 return err; 100 100 101 - fat_time = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) | 101 + hw_counter = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) | 102 102 ((u64) buf[3] << 24) | ((u64) buf[2] << 16) | 103 103 ((u64) buf[1] << 8) | (u64) buf[0]; 104 - time = (unsigned long) (fat_time / 105 - (u64) (AB3100_RTC_CLOCK_RATE * 2)); 104 + time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2); 106 105 } 107 106 108 - rtc_time_to_tm(time, tm); 107 + rtc_time64_to_tm(time, tm); 109 108 110 109 return rtc_valid_tm(tm); 111 110 } 112 111 113 112 static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 114 113 { 115 - unsigned long time; 116 - u64 fat_time; 114 + time64_t time; 115 + u64 hw_counter; 117 116 u8 buf[6]; 118 117 u8 rtcval; 119 118 int err; ··· 133 134 AB3100_AL0, buf, 4); 134 135 if (err) 135 136 return err; 136 - fat_time = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) | 137 + hw_counter = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) | 137 138 ((u64) buf[1] << 24) | ((u64) buf[0] << 16); 138 - time = (unsigned long) (fat_time / (u64) (AB3100_RTC_CLOCK_RATE * 2)); 139 + time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2); 139 140 140 - rtc_time_to_tm(time, &alarm->time); 141 + rtc_time64_to_tm(time, &alarm->time); 141 142 142 143 return rtc_valid_tm(&alarm->time); 143 144 } ··· 146 147 { 147 148 u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3}; 148 149 unsigned char buf[4]; 149 - unsigned long secs; 150 - u64 fat_time; 150 + time64_t secs; 151 + u64 hw_counter; 151 152 int err; 152 153 int i; 153 154 154 - rtc_tm_to_time(&alarm->time, &secs); 155 - fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2; 156 - buf[0] = (fat_time >> 16) & 0xFF; 157 - buf[1] = (fat_time >> 24) & 0xFF; 158 - buf[2] = (fat_time >> 32) & 0xFF; 159 - buf[3] = (fat_time >> 40) & 0xFF; 155 + secs = rtc_tm_to_time64(&alarm->time); 156 + hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2; 157 + buf[0] = (hw_counter >> 16) & 0xFF; 158 + buf[1] = (hw_counter >> 24) & 0xFF; 159 + buf[2] = (hw_counter >> 32) & 0xFF; 160 + buf[3] = (hw_counter >> 40) & 0xFF; 160 161 161 162 /* Set the alarm */ 162 163 for (i = 0; i < 4; i++) { ··· 192 193 193 194 static const struct rtc_class_ops ab3100_rtc_ops = { 194 195 .read_time = ab3100_rtc_read_time, 195 - .set_mmss = ab3100_rtc_set_mmss, 196 + .set_mmss64 = ab3100_rtc_set_mmss, 196 197 .read_alarm = ab3100_rtc_read_alarm, 197 198 .set_alarm = ab3100_rtc_set_alarm, 198 199 .alarm_irq_enable = ab3100_rtc_irq_enable,