[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1417089760-26848-5-git-send-email-pang.xunlei@linaro.org>
Date: Thu, 27 Nov 2014 20:02:40 +0800
From: Xunlei Pang <pang.xunlei@...aro.org>
To: linux-kernel@...r.kernel.org
Cc: rtc-linux@...glegroups.com, Thomas Gleixner <tglx@...utronix.de>,
Alessandro Zummo <a.zummo@...ertech.it>,
Sven Schnelle <svens@...ckframe.org>,
Xunlei Pang <pang.xunlei@...aro.org>,
John Stultz <john.stultz@...aro.org>,
Arnd Bergmann <arnd.bergmann@...aro.org>
Subject: [RFC PATCH 4/4] rtc/imxdi: Update driver to address time issues
The rtc/imxdi rtc driver has a number of y2038/y2106 issues, the worst
one is its hardware only supports 32-bit time.
This patch resolves them based on our foregoing efforts:
- Replace rtc_time_to_tm() with rtc_hw32_to_time64()/rtc_time64_to_tm()
- Replace rtc_tm_to_time() with rtc_tm_to_time64()/rtc_time64_to_hw32()
- Use rtc_time64_to_hw32() to handle dryice_rtc_set_mmss()
After this patch, the drivers should not have any remaining y2038/y2106
issues.
Cc: John Stultz <john.stultz@...aro.org>
Cc: Arnd Bergmann <arnd.bergmann@...aro.org>
Signed-off-by: Xunlei Pang <pang.xunlei@...aro.org>
---
drivers/rtc/rtc-imxdi.c | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 34d76b2..015290f 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -197,10 +197,10 @@ out:
static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct imxdi_dev *imxdi = dev_get_drvdata(dev);
- unsigned long now;
+ time64_t now;
- now = __raw_readl(imxdi->ioaddr + DTCMR);
- rtc_time_to_tm(now, tm);
+ now = rtc_hw32_to_time64(__raw_readl(imxdi->ioaddr + DTCMR));
+ rtc_time64_to_tm(now, tm);
return 0;
}
@@ -213,17 +213,16 @@ static int dryice_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct imxdi_dev *imxdi = dev_get_drvdata(dev);
int rc;
+ u32 hwtime;
+
+ rc = rtc_time64_to_hw32(secs, &hwtime);
+ if (rc < 0)
+ return rc;
/* zero the fractional part first */
rc = di_write_wait(imxdi, 0, DTCLR);
if (rc == 0)
- /*
- * y2106 issue:
- * On 32bit systems the time64_t secs value gets cast to
- * a 32bit long, and thus we can only write a maximum value
- * of y2016
- */
- rc = di_write_wait(imxdi, secs, DTCMR);
+ rc = di_write_wait(imxdi, hwtime, DTCMR);
return rc;
}
@@ -248,10 +247,10 @@ static int dryice_rtc_alarm_irq_enable(struct device *dev,
static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct imxdi_dev *imxdi = dev_get_drvdata(dev);
- u32 dcamr;
+ time64_t alarm_time;
- dcamr = __raw_readl(imxdi->ioaddr + DCAMR);
- rtc_time_to_tm(dcamr, &alarm->time);
+ alarm_time = rtc_hw32_to_time64(__raw_readl(imxdi->ioaddr + DCAMR));
+ rtc_time64_to_tm(alarm_time, &alarm->time);
/* alarm is enabled if the interrupt is enabled */
alarm->enabled = (__raw_readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0;
@@ -273,21 +272,23 @@ static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct imxdi_dev *imxdi = dev_get_drvdata(dev);
- unsigned long now;
- unsigned long alarm_time;
+ time64_t alarm_time, now;
+ u32 alarm_hwtime;
int rc;
- rc = rtc_tm_to_time(&alarm->time, &alarm_time);
- if (rc)
- return rc;
+ alarm_time = rtc_tm_to_time64(&alarm->time);
+ now = rtc_hw32_to_time64(__raw_readl(imxdi->ioaddr + DTCMR));
/* don't allow setting alarm in the past */
- now = __raw_readl(imxdi->ioaddr + DTCMR);
if (alarm_time < now)
return -EINVAL;
+ rc = rtc_time64_to_hw32(alarm_time, &alarm_hwtime);
+ if (rc < 0)
+ return rc;
+
/* write the new alarm time */
- rc = di_write_wait(imxdi, (u32)alarm_time, DCAMR);
+ rc = di_write_wait(imxdi, alarm_hwtime, DCAMR);
if (rc)
return rc;
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists