Re: [PATCH 35/51] rtc: pm8xxx: stop using rtc deprecated functions

From: Arnd Bergmann
Date: Mon Jul 03 2017 - 06:12:11 EST


On Tue, Jun 20, 2017 at 11:35 AM, Benjamin Gaignard
<benjamin.gaignard@xxxxxxxxxx> wrote:
> rtc_time_to_tm() and rtc_tm_to_time() are deprecated because they
> rely on 32bits variables and that will make rtc break in y2038/2016.
> Stop using those two functions to safer 64bits ones.
>
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxx>
> CC: Alessandro Zummo <a.zummo@xxxxxxxxxxxx>
> CC: Alexandre Belloni <alexandre.belloni@xxxxxxxxxxxxxxxxxx>
> CC: rtc-linux@xxxxxxxxxxxxxxxx
> CC: linux-kernel@xxxxxxxxxxxxxxx
> ---
> drivers/rtc/rtc-pm8xxx.c | 22 ++++++++++++----------
> 1 file changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
> index fac8355..e6b52bd 100644
> --- a/drivers/rtc/rtc-pm8xxx.c
> +++ b/drivers/rtc/rtc-pm8xxx.c
> @@ -81,7 +81,8 @@ struct pm8xxx_rtc {
> static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> {
> int rc, i;
> - unsigned long secs, irq_flags;
> + unsigned long long secs;
> + unsigned long irq_flags;

'secs' should be 'time64_t' here, which is signed.

> u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0;
> unsigned int ctrl_reg;
> struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
> @@ -90,14 +91,14 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> if (!rtc_dd->allow_set_time)
> return -EACCES;
>
> - rtc_tm_to_time(tm, &secs);
> + secs = rtc_tm_to_time64(tm);
>
> for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) {
> value[i] = secs & 0xFF;
> secs >>= 8;
> }
>
> - dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs);
> + dev_dbg(dev, "Seconds value to be written to RTC = %llu\n", secs);
>

However, note that you only write 32 bits here, since NUM_8_BIT_RTC_REGS
is set to '4'. Is that a hardware constant? If yes, it would be best to return
-EINVAL or -EOVERFLOW for out of range times.

I think should really try to come up with a way to set the policy for
overflows in
RTC drivers globally in this case. There are many drivers that take a 32-bit
unsigned value (and many others that don't), but a nicer policy for the long
run might be to define some kind of windowing where values before e.g.
year 2000 or 2017 are wrapped around and used as future dates.

Unfortunately, the downside of this is that any RTC that defaults to '0'
and is now interpreted as year 1970 would then be interpreted as a future
data that can not be represented in today's 32-bit time_t.

Arnd