aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-02-18 08:26:06 -0500
committerJason Cooper <jason@lakedaemon.net>2014-02-21 18:29:05 -0500
commite102dc7a5498439bf72ae9f6457f2e7fe09a4ae0 (patch)
tree3b93a9f8c33eeb947a1be61b18c2e2dfe9b044e2
parent00b28184b1f148a60a08ddc2efd220ec4da32726 (diff)
rtc: mv: reset date if after year 2038
Dates after January, 19th 2038 are badly handled by userspace due to the time being stored on 32 bits. This causes issues on some Marvell platform on which the RTC is initialized by default to a date that's beyond 2038, causing a really weird behavior of the RTC. In order to avoid that, reset the date to a sane value if the RTC is beyond 2038. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--drivers/rtc/rtc-mv.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index d536c5962c99..d15a999363fc 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -222,6 +222,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
222 struct resource *res; 222 struct resource *res;
223 struct rtc_plat_data *pdata; 223 struct rtc_plat_data *pdata;
224 u32 rtc_time; 224 u32 rtc_time;
225 u32 rtc_date;
225 int ret = 0; 226 int ret = 0;
226 227
227 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 228 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
@@ -257,6 +258,17 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
257 } 258 }
258 } 259 }
259 260
261 /*
262 * A date after January 19th, 2038 does not fit on 32 bits and
263 * will confuse the kernel and userspace. Reset to a sane date
264 * (January 1st, 2013) if we're after 2038.
265 */
266 rtc_date = readl(pdata->ioaddr + RTC_DATE_REG_OFFS);
267 if (bcd2bin((rtc_date >> RTC_YEAR_OFFS) & 0xff) >= 38) {
268 dev_info(&pdev->dev, "invalid RTC date, resetting to January 1st, 2013\n");
269 writel(0x130101, pdata->ioaddr + RTC_DATE_REG_OFFS);
270 }
271
260 pdata->irq = platform_get_irq(pdev, 0); 272 pdata->irq = platform_get_irq(pdev, 0);
261 273
262 platform_set_drvdata(pdev, pdata); 274 platform_set_drvdata(pdev, pdata);