aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXunlei Pang <pang.xunlei@linaro.org>2015-06-11 22:04:12 -0400
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2015-06-24 19:13:42 -0400
commit9033fd8ba7e96821e65fe3afc3f4077a8b66d1c9 (patch)
treeae0657008e5171227c211bf488f818ba92d161f7
parentf118db1efdbd224b3e0dd174a8942471eee798a0 (diff)
rtc: sunxi: Replace deprecated rtc_tm_to_time()
sunxi_rtc_setalarm() uses deprecated rtc_tm_to_time(), which will overflow in year 2106 on 32-bit machines. This patch solves this by: - Replacing rtc_tm_to_time() with rtc_tm_sub() Also remove the unnecessary initial zeroing of some local variables in sunxi_rtc_setalarm(). Cc: Carlo Caione <carlo.caione@gmail.com> Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-rw-r--r--drivers/rtc/rtc-sunxi.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c
index 6e678fa4dfaf..52543ae37c98 100644
--- a/drivers/rtc/rtc-sunxi.c
+++ b/drivers/rtc/rtc-sunxi.c
@@ -269,14 +269,13 @@ static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
269 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev); 269 struct sunxi_rtc_dev *chip = dev_get_drvdata(dev);
270 struct rtc_time *alrm_tm = &wkalrm->time; 270 struct rtc_time *alrm_tm = &wkalrm->time;
271 struct rtc_time tm_now; 271 struct rtc_time tm_now;
272 u32 alrm = 0; 272 u32 alrm;
273 unsigned long time_now = 0; 273 time64_t diff;
274 unsigned long time_set = 0; 274 unsigned long time_gap;
275 unsigned long time_gap = 0; 275 unsigned long time_gap_day;
276 unsigned long time_gap_day = 0; 276 unsigned long time_gap_hour;
277 unsigned long time_gap_hour = 0; 277 unsigned long time_gap_min;
278 unsigned long time_gap_min = 0; 278 int ret;
279 int ret = 0;
280 279
281 ret = sunxi_rtc_gettime(dev, &tm_now); 280 ret = sunxi_rtc_gettime(dev, &tm_now);
282 if (ret < 0) { 281 if (ret < 0) {
@@ -284,14 +283,18 @@ static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
284 return -EINVAL; 283 return -EINVAL;
285 } 284 }
286 285
287 rtc_tm_to_time(alrm_tm, &time_set); 286 diff = rtc_tm_sub(alrm_tm, &tm_now);
288 rtc_tm_to_time(&tm_now, &time_now); 287 if (diff <= 0) {
289 if (time_set <= time_now) {
290 dev_err(dev, "Date to set in the past\n"); 288 dev_err(dev, "Date to set in the past\n");
291 return -EINVAL; 289 return -EINVAL;
292 } 290 }
293 291
294 time_gap = time_set - time_now; 292 if (diff > 255 * SEC_IN_DAY) {
293 dev_err(dev, "Day must be in the range 0 - 255\n");
294 return -EINVAL;
295 }
296
297 time_gap = diff;
295 time_gap_day = time_gap / SEC_IN_DAY; 298 time_gap_day = time_gap / SEC_IN_DAY;
296 time_gap -= time_gap_day * SEC_IN_DAY; 299 time_gap -= time_gap_day * SEC_IN_DAY;
297 time_gap_hour = time_gap / SEC_IN_HOUR; 300 time_gap_hour = time_gap / SEC_IN_HOUR;
@@ -299,11 +302,6 @@ static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
299 time_gap_min = time_gap / SEC_IN_MIN; 302 time_gap_min = time_gap / SEC_IN_MIN;
300 time_gap -= time_gap_min * SEC_IN_MIN; 303 time_gap -= time_gap_min * SEC_IN_MIN;
301 304
302 if (time_gap_day > 255) {
303 dev_err(dev, "Day must be in the range 0 - 255\n");
304 return -EINVAL;
305 }
306
307 sunxi_rtc_setaie(0, chip); 305 sunxi_rtc_setaie(0, chip);
308 writel(0, chip->base + SUNXI_ALRM_DHMS); 306 writel(0, chip->base + SUNXI_ALRM_DHMS);
309 usleep_range(100, 300); 307 usleep_range(100, 300);