@@ -116,7 +116,7 @@ alpha_rtc_set_time(struct device *dev, struct rtc_time *tm)
}
static int
-alpha_rtc_set_mmss(struct device *dev, unsigned long nowtime)
+alpha_rtc_set_mmss(struct device *dev, time64_t nowtime)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
@@ -276,7 +276,7 @@ do_remote_mmss(void *data)
}
static int
-remote_set_mmss(struct device *dev, unsigned long now)
+remote_set_mmss(struct device *dev, time64_t now)
{
union remote_data x;
if (smp_processor_id() != boot_cpuid) {
@@ -65,10 +65,10 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
else if (rtc->ops->set_time)
err = rtc->ops->set_time(rtc->dev.parent, tm);
else if (rtc->ops->set_mmss) {
- unsigned long secs;
- err = rtc_tm_to_time(tm, &secs);
- if (err == 0)
- err = rtc->ops->set_mmss(rtc->dev.parent, secs);
+ time64_t secs;
+
+ secs = rtc_tm_to_time64(tm);
+ err = rtc->ops->set_mmss(rtc->dev.parent, secs);
} else
err = -EINVAL;
@@ -43,12 +43,12 @@
/*
* RTC clock functions and device struct declaration
*/
-static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int ab3100_rtc_set_mmss(struct device *dev, time64_t secs)
{
u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2,
AB3100_TI3, AB3100_TI4, AB3100_TI5};
unsigned char buf[6];
- u64 fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2;
+ time64_t fat_time = secs * AB3100_RTC_CLOCK_RATE * 2;
int err = 0;
int i;
@@ -88,11 +88,17 @@ static int coh901331_read_time(struct device *dev, struct rtc_time *tm)
return -EINVAL;
}
-static int coh901331_set_mmss(struct device *dev, unsigned long secs)
+static int coh901331_set_mmss(struct device *dev, time64_t secs)
{
struct coh901331_port *rtap = dev_get_drvdata(dev);
clk_enable(rtap->clk);
+ /*
+ * 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
+ */
writel(secs, rtap->virtbase + COH901331_SET_TIME);
clk_disable(rtap->clk);
@@ -98,8 +98,14 @@ static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm)
return ds1672_get_datetime(to_i2c_client(dev), tm);
}
-static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int ds1672_rtc_set_mmss(struct device *dev, time64_t secs)
{
+ /*
+ * 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
+ */
return ds1672_set_mmss(to_i2c_client(dev), secs);
}
@@ -210,9 +210,16 @@ static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
return rtc_valid_tm(dt);
}
-static int ds2404_set_mmss(struct device *dev, unsigned long secs)
+static int ds2404_set_mmss(struct device *dev, time64_t secs)
{
+ /*
+ * 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
+ */
u32 time = cpu_to_le32(secs);
+
ds2404_write_memory(dev, 0x203, 4, (u8 *)&time);
return 0;
}
@@ -69,10 +69,16 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
return 0;
}
-static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int ep93xx_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev);
+ /*
+ * 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
+ */
__raw_writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD);
return 0;
}
@@ -209,7 +209,7 @@ static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm)
* set the seconds portion of dryice time counter and clear the
* fractional part.
*/
-static int dryice_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int dryice_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct imxdi_dev *imxdi = dev_get_drvdata(dev);
int rc;
@@ -217,6 +217,12 @@ static int dryice_rtc_set_mmss(struct device *dev, unsigned long secs)
/* 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);
return rc;
@@ -127,10 +127,16 @@ static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
return rtc_valid_tm(time);
}
-static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int jz4740_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct jz4740_rtc *rtc = dev_get_drvdata(dev);
+ /*
+ * 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
+ */
return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs);
}
@@ -73,7 +73,7 @@ static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time)
return rtc_valid_tm(time);
}
-static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int lpc32xx_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct lpc32xx_rtc *rtc = dev_get_drvdata(dev);
u32 tmp;
@@ -83,6 +83,13 @@ static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs)
/* RTC must be disabled during count update */
tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL);
rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | LPC32XX_RTC_CTRL_CNTR_DIS);
+
+ /*
+ * 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
+ */
rtc_writel(rtc, LPC32XX_RTC_UCOUNT, secs);
rtc_writel(rtc, LPC32XX_RTC_DCOUNT, 0xFFFFFFFF - secs);
rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp &= ~LPC32XX_RTC_CTRL_CNTR_DIS);
@@ -88,15 +88,14 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
return rtc_valid_tm(tm);
}
-static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
unsigned int seconds, days;
unsigned int alarmseconds;
int ret;
- seconds = secs % SEC_PER_DAY;
- days = secs / SEC_PER_DAY;
+ days = div_s64_rem(secs, SEC_PER_DAY, &seconds);
mc13xxx_lock(priv->mc13xxx);
@@ -297,7 +297,7 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
/*
* This function sets the internal RTC time based on tm in Gregorian date.
*/
-static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
+static int mxc_rtc_set_mmss(struct device *dev, time64_t time)
{
struct platform_device *pdev = to_platform_device(dev);
struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
@@ -308,9 +308,9 @@ static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
if (is_imx1_rtc(pdata)) {
struct rtc_time tm;
- rtc_time_to_tm(time, &tm);
+ rtc_time64_to_tm(time, &tm);
tm.tm_year = 70;
- rtc_tm_to_time(&tm, &time);
+ time = rtc_tm_to_time64(&tm);
}
/* Avoid roll-over from reading the different registers */
@@ -98,16 +98,14 @@ static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
return rtc_valid_tm(tm);
}
-static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int pcap_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct platform_device *pdev = to_platform_device(dev);
struct pcap_rtc *pcap_rtc = platform_get_drvdata(pdev);
u32 tod, days;
- tod = secs % SEC_PER_DAY;
+ days = div_s64_rem(secs, SEC_PER_DAY, &tod);
ezx_pcap_write(pcap_rtc->pcap, PCAP_REG_RTC_TOD, tod);
-
- days = secs / SEC_PER_DAY;
ezx_pcap_write(pcap_rtc->pcap, PCAP_REG_RTC_DAY, days);
return 0;
@@ -157,10 +157,16 @@ static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
return 0;
}
-static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t)
+static int stmp3xxx_rtc_set_mmss(struct device *dev, time64_t t)
{
struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev);
+ /*
+ * 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
+ */
writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS);
return stmp3xxx_wait_time(rtc_data);
}
@@ -34,9 +34,9 @@ static int test_rtc_read_time(struct device *dev,
return 0;
}
-static int test_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int test_rtc_set_mmss(struct device *dev, time64_t secs)
{
- dev_info(dev, "%s, secs = %lu\n", __func__, secs);
+ dev_info(dev, "%s, secs = %lld\n", __func__, (long long)secs);
return 0;
}
@@ -42,13 +42,19 @@ static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd)
return 0;
}
-static int tx4939_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int tx4939_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
int i, ret;
unsigned char buf[6];
+ /*
+ * 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
+ */
buf[0] = 0;
buf[1] = 0;
buf[2] = secs;
@@ -169,15 +169,21 @@ static int wm831x_rtc_readtime(struct device *dev, struct rtc_time *tm)
/*
* Set current time and date in RTC
*/
-static int wm831x_rtc_set_mmss(struct device *dev, unsigned long time)
+static int wm831x_rtc_set_mmss(struct device *dev, time64_t time)
{
struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
struct wm831x *wm831x = wm831x_rtc->wm831x;
struct rtc_time new_tm;
- unsigned long new_time;
+ time64_t new_time;
int ret;
int count = 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
+ */
ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_1,
(time >> 16) & 0xffff);
if (ret < 0) {
@@ -215,11 +221,7 @@ static int wm831x_rtc_set_mmss(struct device *dev, unsigned long time)
if (ret < 0)
return ret;
- ret = rtc_tm_to_time(&new_tm, &new_time);
- if (ret < 0) {
- dev_err(dev, "Failed to convert time: %d\n", ret);
- return ret;
- }
+ new_time = rtc_tm_to_time64(&new_tm);
/* Allow a second of change in case of tick */
if (new_time - time > 1) {
@@ -62,13 +62,17 @@ static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm)
return rtc_valid_tm(tm);
}
-static int xgene_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int xgene_rtc_set_mmss(struct device *dev, time64_t secs)
{
struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
/*
* NOTE: After the following write, the RTC_CCVR is only reflected
* after the update cycle of 1 seconds.
+ * 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
*/
writel((u32) secs, pdata->csr_base + RTC_CLR);
readl(pdata->csr_base + RTC_CLR); /* Force a barrier */
@@ -77,7 +77,7 @@ struct rtc_class_ops {
int (*read_alarm)(struct device *, struct rtc_wkalrm *);
int (*set_alarm)(struct device *, struct rtc_wkalrm *);
int (*proc)(struct device *, struct seq_file *);
- int (*set_mmss)(struct device *, unsigned long secs);
+ int (*set_mmss)(struct device *, time64_t secs);
int (*read_callback)(struct device *, int data);
int (*alarm_irq_enable)(struct device *, unsigned int enabled);
};
Currently the rtc_class_op's set_mmss() function takes a 32bit second value (on 32bit systems), which is problematic for dates past y2038. This patch resolves it by changing the interface and all users to use y2038 safe time64_t. Cc: John Stultz <john.stultz@linaro.org> Cc: Arnd Bergmann <arnd.bergmann@linaro.org> Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org> --- This patch leaves some "y2106 issue" tags in the problematic drivers whose rtc hardware only provides 32bit time. The handling of these problematic drivers will be left to the succeeding patch series. But, to better understand the purpose of this patch series, one of those drivers is picked and resolved in the last patch as an example. arch/alpha/kernel/rtc.c | 4 ++-- drivers/rtc/interface.c | 8 ++++---- drivers/rtc/rtc-ab3100.c | 4 ++-- drivers/rtc/rtc-coh901331.c | 8 +++++++- drivers/rtc/rtc-ds1672.c | 8 +++++++- drivers/rtc/rtc-ds2404.c | 9 ++++++++- drivers/rtc/rtc-ep93xx.c | 8 +++++++- drivers/rtc/rtc-imxdi.c | 8 +++++++- drivers/rtc/rtc-jz4740.c | 8 +++++++- drivers/rtc/rtc-lpc32xx.c | 9 ++++++++- drivers/rtc/rtc-mc13xxx.c | 5 ++--- drivers/rtc/rtc-mxc.c | 6 +++--- drivers/rtc/rtc-pcap.c | 6 ++---- drivers/rtc/rtc-stmp3xxx.c | 8 +++++++- drivers/rtc/rtc-test.c | 4 ++-- drivers/rtc/rtc-tx4939.c | 8 +++++++- drivers/rtc/rtc-wm831x.c | 16 +++++++++------- drivers/rtc/rtc-xgene.c | 6 +++++- include/linux/rtc.h | 2 +- 19 files changed, 97 insertions(+), 38 deletions(-)