74 lines
2.4 KiB
Diff
74 lines
2.4 KiB
Diff
From 8ac06a34de49b9dab7889d9e0693466d3cca10e7 Mon Sep 17 00:00:00 2001
|
|
From: Andre Przywara <andre.przywara@arm.com>
|
|
Date: Fri, 18 Jun 2021 14:37:56 +0100
|
|
Subject: [PATCH 010/101] drv:rtc:sun6i: Fix time overflow handling
|
|
|
|
Using "unsigned long" for UNIX timestamps is never a good idea, and
|
|
comparing the value of such a variable against U32_MAX does not do
|
|
anything useful on 32-bit systems.
|
|
|
|
Use the proper time64_t type when dealing with timestamps, and avoid
|
|
cutting down the time range unnecessarily. This also fixes the flawed
|
|
check for the alarm time being too far into the future.
|
|
|
|
The check for this condition is actually somewhat theoretical, as the
|
|
RTC counts till 2033 only anyways, and 2^32 seconds from now is not
|
|
before the year 2157 - at which point I hope nobody will be using this
|
|
hardware anymore.
|
|
|
|
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
|
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
|
|
---
|
|
drivers/rtc/rtc-sun6i.c | 14 +++++---------
|
|
1 file changed, 5 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
|
|
index 50de48cf6..f1328ddbf 100644
|
|
--- a/drivers/rtc/rtc-sun6i.c
|
|
+++ b/drivers/rtc/rtc-sun6i.c
|
|
@@ -142,7 +142,7 @@ struct sun6i_rtc_dev {
|
|
const struct sun6i_rtc_clk_data *data;
|
|
void __iomem *base;
|
|
int irq;
|
|
- unsigned long alarm;
|
|
+ time64_t alarm;
|
|
|
|
struct clk_hw hw;
|
|
struct clk_hw *int_osc;
|
|
@@ -514,10 +514,8 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
|
|
struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
|
|
struct rtc_time *alrm_tm = &wkalrm->time;
|
|
struct rtc_time tm_now;
|
|
- unsigned long time_now = 0;
|
|
- unsigned long time_set = 0;
|
|
- unsigned long time_gap = 0;
|
|
- int ret = 0;
|
|
+ time64_t time_now, time_set;
|
|
+ int ret;
|
|
|
|
ret = sun6i_rtc_gettime(dev, &tm_now);
|
|
if (ret < 0) {
|
|
@@ -532,9 +530,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
|
|
return -EINVAL;
|
|
}
|
|
|
|
- time_gap = time_set - time_now;
|
|
-
|
|
- if (time_gap > U32_MAX) {
|
|
+ if ((time_set - time_now) > U32_MAX) {
|
|
dev_err(dev, "Date too far in the future\n");
|
|
return -EINVAL;
|
|
}
|
|
@@ -543,7 +539,7 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
|
|
writel(0, chip->base + SUN6I_ALRM_COUNTER);
|
|
usleep_range(100, 300);
|
|
|
|
- writel(time_gap, chip->base + SUN6I_ALRM_COUNTER);
|
|
+ writel(time_set - time_now, chip->base + SUN6I_ALRM_COUNTER);
|
|
chip->alarm = time_set;
|
|
|
|
sun6i_rtc_setaie(wkalrm->enabled, chip);
|
|
--
|
|
2.31.1
|
|
|