On 32bits platforms "struct timeval" or "time_t" are using u32 to code the
date, this cause tools like "date" or "hwclock" failed even before setting
the RTC device if the date is superior to year 2038 (or 2106).
To avoid this problem I add two RTC tests files which directly use RTC ioctl
to set and read RTC time and alarm values.
rtctest_setdate allow to set any date/time given in the command line.
rtctest-2038 perform a basic test by writing 1-1-2200 in RTC time and alarm
and checking that the read back values are correct.
Finally that had allowed me to test and fix rtc-st-lpc driver.
Benjamin Gaignard (3):
tools: timer: add rtctest_setdate
tools: timer: add test to check y2038/2106 bug
rtc: st-lpc: make it robust against y2038/2106 bug
drivers/rtc/rtc-st-lpc.c | 19 ++--
tools/testing/selftests/timers/Makefile | 4 +-
tools/testing/selftests/timers/rtctest-2038.c | 135 +++++++++++++++++++++++
tools/testing/selftests/timers/rtctest_setdate.c | 86 +++++++++++++++
4 files changed, 232 insertions(+), 12 deletions(-)
create mode 100644 tools/testing/selftests/timers/rtctest-2038.c
create mode 100644 tools/testing/selftests/timers/rtctest_setdate.c
--
1.9.1
This tool allow to set directly the time and date to a RTC device.
Unlike other tools isn't doens't use "strut timeval" or "time_t"
so it is safe for 32bits platforms when testing for y2038/2106 bug.
Signed-off-by: Benjamin Gaignard <[email protected]>
---
tools/testing/selftests/timers/Makefile | 2 +-
tools/testing/selftests/timers/rtctest_setdate.c | 86 ++++++++++++++++++++++++
2 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/timers/rtctest_setdate.c
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 5fa1d7e9..54481f1 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -9,7 +9,7 @@ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
skew_consistency clocksource-switch leap-a-day \
- leapcrash set-tai set-2038 set-tz
+ leapcrash set-tai set-2038 set-tz rtctest_setdate
include ../lib.mk
diff --git a/tools/testing/selftests/timers/rtctest_setdate.c b/tools/testing/selftests/timers/rtctest_setdate.c
new file mode 100644
index 0000000..2cb7848
--- /dev/null
+++ b/tools/testing/selftests/timers/rtctest_setdate.c
@@ -0,0 +1,86 @@
+/* Real Time Clock Driver Test
+ * by: Benjamin Gaignard ([email protected])
+ *
+ * To build
+ * gcc rtctest_setdate.c -o rtctest_setdate
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <linux/rtc.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+static const char default_time[] = "00:00:00";
+
+int main(int argc, char **argv)
+{
+ int fd, retval;
+ struct rtc_time new, current;
+ const char *rtc, *date;
+ const char *time = default_time;
+
+ switch (argc) {
+ case 4:
+ time = argv[3];
+ /* FALLTHROUGH */
+ case 3:
+ date = argv[2];
+ rtc = argv[1];
+ break;
+ default:
+ fprintf(stderr, "usage: rtctest_setdate <rtcdev> <DD-MM-YYYY> [HH:MM:SS]\n");
+ return 1;
+ }
+
+ fd = open(rtc, O_RDONLY);
+ if (fd == -1) {
+ perror(rtc);
+ exit(errno);
+ }
+
+ sscanf(date, "%d-%d-%d", &new.tm_mday, &new.tm_mon, &new.tm_year);
+ new.tm_mon -= 1;
+ new.tm_year -= 1900;
+ sscanf(time, "%d:%d:%d", &new.tm_hour, &new.tm_min, &new.tm_sec);
+
+ fprintf(stderr, "Test will set RTC date/time to %d-%d-%d, %02d:%02d:%02d.\n",
+ new.tm_mday, new.tm_mon + 1, new.tm_year + 1900,
+ new.tm_hour, new.tm_min, new.tm_sec);
+
+ /* Write the new date in RTC */
+ retval = ioctl(fd, RTC_SET_TIME, &new);
+ if (retval == -1) {
+ perror("RTC_SET_TIME ioctl");
+ close(fd);
+ exit(errno);
+ }
+
+ /* Read back */
+ retval = ioctl(fd, RTC_RD_TIME, ¤t);
+ if (retval == -1) {
+ perror("RTC_RD_TIME ioctl");
+ exit(errno);
+ }
+
+ fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
+ current.tm_mday, current.tm_mon + 1, current.tm_year + 1900,
+ current.tm_hour, current.tm_min, current.tm_sec);
+
+ close(fd);
+ return 0;
+}
--
1.9.1
The goal of this test is to check if a RTC device correctly support
dates after years 2038 or 2106.
It set a date (1-1-2200) on RTC and read it back to be sure that the
driver is working well.
The same thing is done on alarm.
Signed-off-by: Benjamin Gaignard <[email protected]>
---
tools/testing/selftests/timers/Makefile | 4 +-
tools/testing/selftests/timers/rtctest-2038.c | 135 ++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/timers/rtctest-2038.c
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 54481f1..7791f79 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -9,7 +9,8 @@ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
skew_consistency clocksource-switch leap-a-day \
- leapcrash set-tai set-2038 set-tz rtctest_setdate
+ leapcrash set-tai set-2038 set-tz rtctest_setdate \
+ rtctest-2038
include ../lib.mk
@@ -29,4 +30,5 @@ run_destructive_tests: run_tests
./set-tz
./set-tai
./set-2038
+ ./rtctest-2038
diff --git a/tools/testing/selftests/timers/rtctest-2038.c b/tools/testing/selftests/timers/rtctest-2038.c
new file mode 100644
index 0000000..213b7ee
--- /dev/null
+++ b/tools/testing/selftests/timers/rtctest-2038.c
@@ -0,0 +1,135 @@
+/* Real Time Clock Driver Test
+ * by: Benjamin Gaignard ([email protected])
+ *
+ * To build
+ * gcc rtctest-2038.c -o rtctest-2038
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <linux/rtc.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+static const char default_rtc[] = "/dev/rtc0";
+
+int main(int argc, char **argv)
+{
+ int fd, retval;
+ struct rtc_time new, current;
+ const char *rtc = default_rtc;
+
+ switch (argc) {
+ case 2:
+ rtc = argv[1];
+ /* FALLTHROUGH */
+ case 1:
+ break;
+ default:
+ fprintf(stderr, "usage: rtctest-2038 [rtcdev]\n");
+ return 1;
+ }
+
+ fprintf(stderr, "\nTest if RTC is robust for date after y2038/2106\n\n");
+
+ fd = open(rtc, O_RDONLY);
+ if (fd == -1) {
+ perror(rtc);
+ exit(errno);
+ }
+
+ new.tm_year = 300; /* 2200 - 1900 */
+ new.tm_mon = 0;
+ new.tm_mday = 1;
+ new.tm_hour = 0;
+ new.tm_min = 0;
+ new.tm_sec = 0;
+
+ fprintf(stderr, "Test will set RTC date/time to %d-%d-%d, %02d:%02d:%02d.\n",
+ new.tm_mday, new.tm_mon + 1, new.tm_year + 1900,
+ new.tm_hour, new.tm_min, new.tm_sec);
+
+ /* Write the new date in RTC */
+ retval = ioctl(fd, RTC_SET_TIME, &new);
+ if (retval == -1) {
+ perror("RTC_SET_TIME ioctl");
+ close(fd);
+ exit(errno);
+ }
+
+ /* Read back */
+ retval = ioctl(fd, RTC_RD_TIME, ¤t);
+ if (retval == -1) {
+ perror("RTC_RD_TIME ioctl");
+ exit(errno);
+ }
+
+ fprintf(stderr, "RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
+ current.tm_mday, current.tm_mon + 1, current.tm_year + 1900,
+ current.tm_hour, current.tm_min, current.tm_sec);
+
+ if (new.tm_year != current.tm_year ||
+ new.tm_mon != current.tm_mon ||
+ new.tm_mday != current.tm_mday ||
+ new.tm_hour != current.tm_hour ||
+ new.tm_min != current.tm_min ||
+ new.tm_sec != current.tm_sec) {
+ fprintf(stderr, "\n\nSet Time test failed\n");
+ close(fd);
+ return 1;
+ }
+
+ new.tm_sec += 5;
+
+ fprintf(stderr, "\nTest will set RTC alarm to %d-%d-%d, %02d:%02d:%02d.\n",
+ new.tm_mday, new.tm_mon + 1, new.tm_year + 1900,
+ new.tm_hour, new.tm_min, new.tm_sec);
+
+ /* Write the new alarm in RTC */
+ retval = ioctl(fd, RTC_ALM_SET, &new);
+ if (retval == -1) {
+ perror("RTC_ALM_SET ioctl");
+ close(fd);
+ exit(errno);
+ }
+
+ /* Read back */
+ retval = ioctl(fd, RTC_ALM_READ, ¤t);
+ if (retval == -1) {
+ perror("RTC_ALM_READ ioctl");
+ exit(errno);
+ }
+
+ fprintf(stderr, "RTC alarm is %d-%d-%d, %02d:%02d:%02d.\n",
+ current.tm_mday, current.tm_mon + 1, current.tm_year + 1900,
+ current.tm_hour, current.tm_min, current.tm_sec);
+
+ if (new.tm_year != current.tm_year ||
+ new.tm_mon != current.tm_mon ||
+ new.tm_mday != current.tm_mday ||
+ new.tm_hour != current.tm_hour ||
+ new.tm_min != current.tm_min ||
+ new.tm_sec != current.tm_sec) {
+ fprintf(stderr, "\n\nSet alarm test failed\n");
+ close(fd);
+ return 1;
+ }
+
+ fprintf(stderr, "\nTest complete\n");
+ close(fd);
+ return 0;
+}
--
1.9.1
Make driver use u64 variables and functions to be sure that
it will support dates after year 2038.
Signed-off-by: Benjamin Gaignard <[email protected]>
---
drivers/rtc/rtc-st-lpc.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
index 74c0a33..82b0af1 100644
--- a/drivers/rtc/rtc-st-lpc.c
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -99,7 +99,7 @@ static int st_rtc_read_time(struct device *dev, struct rtc_time *tm)
lpt = ((unsigned long long)lpt_msb << 32) | lpt_lsb;
do_div(lpt, rtc->clkrate);
- rtc_time_to_tm(lpt, tm);
+ rtc_time64_to_tm(lpt, tm);
return 0;
}
@@ -107,13 +107,10 @@ static int st_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int st_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct st_rtc *rtc = dev_get_drvdata(dev);
- unsigned long long lpt;
- unsigned long secs, flags;
- int ret;
+ unsigned long long lpt, secs;
+ unsigned long flags;
- ret = rtc_tm_to_time(tm, &secs);
- if (ret)
- return ret;
+ secs = rtc_tm_to_time64(tm);
lpt = (unsigned long long)secs * rtc->clkrate;
@@ -161,13 +158,13 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct st_rtc *rtc = dev_get_drvdata(dev);
struct rtc_time now;
- unsigned long now_secs;
- unsigned long alarm_secs;
+ unsigned long long now_secs;
+ unsigned long long alarm_secs;
unsigned long long lpa;
st_rtc_read_time(dev, &now);
- rtc_tm_to_time(&now, &now_secs);
- rtc_tm_to_time(&t->time, &alarm_secs);
+ now_secs = rtc_tm_to_time64(&now);
+ alarm_secs = rtc_tm_to_time64(&t->time);
/* Invalid alarm time */
if (now_secs > alarm_secs)
--
1.9.1
On 06/16/2017 08:03 AM, Benjamin Gaignard wrote:
> On 32bits platforms "struct timeval" or "time_t" are using u32 to code the
> date, this cause tools like "date" or "hwclock" failed even before setting
> the RTC device if the date is superior to year 2038 (or 2106).
>
> To avoid this problem I add two RTC tests files which directly use RTC ioctl
> to set and read RTC time and alarm values.
> rtctest_setdate allow to set any date/time given in the command line.
> rtctest-2038 perform a basic test by writing 1-1-2200 in RTC time and alarm
> and checking that the read back values are correct.
>
> Finally that had allowed me to test and fix rtc-st-lpc driver.
>
> Benjamin Gaignard (3):
> tools: timer: add rtctest_setdate
> tools: timer: add test to check y2038/2106 bug
> rtc: st-lpc: make it robust against y2038/2106 bug
>
> drivers/rtc/rtc-st-lpc.c | 19 ++--
> tools/testing/selftests/timers/Makefile | 4 +-
> tools/testing/selftests/timers/rtctest-2038.c | 135 +++++++++++++++++++++++
> tools/testing/selftests/timers/rtctest_setdate.c | 86 +++++++++++++++
> 4 files changed, 232 insertions(+), 12 deletions(-)
> create mode 100644 tools/testing/selftests/timers/rtctest-2038.c
> create mode 100644 tools/testing/selftests/timers/rtctest_setdate.c
>
Hi John/Thomas,
Please review them and let me know. Looks to me these will make good
additions to 4.13-rc1 kselftest content.
thanks,
-- Shuah
Hi,
On 16/06/2017 at 16:03:51 +0200, Benjamin Gaignard wrote:
> This tool allow to set directly the time and date to a RTC device.
>
> Unlike other tools isn't doens't use "strut timeval" or "time_t"
A small typo here-----^
> so it is safe for 32bits platforms when testing for y2038/2106 bug.
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> tools/testing/selftests/timers/Makefile | 2 +-
> tools/testing/selftests/timers/rtctest_setdate.c | 86 ++++++++++++++++++++++++
> 2 files changed, 87 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/timers/rtctest_setdate.c
>
> diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
> index 5fa1d7e9..54481f1 100644
> --- a/tools/testing/selftests/timers/Makefile
> +++ b/tools/testing/selftests/timers/Makefile
> @@ -9,7 +9,7 @@ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
>
> TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
> skew_consistency clocksource-switch leap-a-day \
> - leapcrash set-tai set-2038 set-tz
> + leapcrash set-tai set-2038 set-tz rtctest_setdate
>
>
> include ../lib.mk
> diff --git a/tools/testing/selftests/timers/rtctest_setdate.c b/tools/testing/selftests/timers/rtctest_setdate.c
> new file mode 100644
> index 0000000..2cb7848
> --- /dev/null
> +++ b/tools/testing/selftests/timers/rtctest_setdate.c
> @@ -0,0 +1,86 @@
> +/* Real Time Clock Driver Test
> + * by: Benjamin Gaignard ([email protected])
> + *
> + * To build
> + * gcc rtctest_setdate.c -o rtctest_setdate
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <stdio.h>
> +#include <linux/rtc.h>
> +#include <sys/ioctl.h>
> +#include <sys/time.h>
> +#include <sys/types.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +
> +static const char default_time[] = "00:00:00";
> +
> +int main(int argc, char **argv)
> +{
> + int fd, retval;
> + struct rtc_time new, current;
> + const char *rtc, *date;
> + const char *time = default_time;
> +
> + switch (argc) {
> + case 4:
> + time = argv[3];
> + /* FALLTHROUGH */
> + case 3:
> + date = argv[2];
> + rtc = argv[1];
> + break;
> + default:
> + fprintf(stderr, "usage: rtctest_setdate <rtcdev> <DD-MM-YYYY> [HH:MM:SS]\n");
> + return 1;
> + }
> +
> + fd = open(rtc, O_RDONLY);
> + if (fd == -1) {
> + perror(rtc);
> + exit(errno);
> + }
> +
> + sscanf(date, "%d-%d-%d", &new.tm_mday, &new.tm_mon, &new.tm_year);
> + new.tm_mon -= 1;
> + new.tm_year -= 1900;
> + sscanf(time, "%d:%d:%d", &new.tm_hour, &new.tm_min, &new.tm_sec);
> +
> + fprintf(stderr, "Test will set RTC date/time to %d-%d-%d, %02d:%02d:%02d.\n",
> + new.tm_mday, new.tm_mon + 1, new.tm_year + 1900,
> + new.tm_hour, new.tm_min, new.tm_sec);
> +
> + /* Write the new date in RTC */
> + retval = ioctl(fd, RTC_SET_TIME, &new);
> + if (retval == -1) {
> + perror("RTC_SET_TIME ioctl");
> + close(fd);
> + exit(errno);
> + }
> +
> + /* Read back */
> + retval = ioctl(fd, RTC_RD_TIME, ¤t);
> + if (retval == -1) {
> + perror("RTC_RD_TIME ioctl");
> + exit(errno);
> + }
> +
> + fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
> + current.tm_mday, current.tm_mon + 1, current.tm_year + 1900,
> + current.tm_hour, current.tm_min, current.tm_sec);
> +
> + close(fd);
> + return 0;
> +}
> --
> 1.9.1
>
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
On 16/06/2017 at 16:03:52 +0200, Benjamin Gaignard wrote:
> The goal of this test is to check if a RTC device correctly support
> dates after years 2038 or 2106.
> It set a date (1-1-2200) on RTC and read it back to be sure that the
> driver is working well.
> The same thing is done on alarm.
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> tools/testing/selftests/timers/Makefile | 4 +-
> tools/testing/selftests/timers/rtctest-2038.c | 135 ++++++++++++++++++++++++++
> 2 files changed, 138 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/timers/rtctest-2038.c
>
> diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
> index 54481f1..7791f79 100644
> --- a/tools/testing/selftests/timers/Makefile
> +++ b/tools/testing/selftests/timers/Makefile
> @@ -9,7 +9,8 @@ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
>
> TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
> skew_consistency clocksource-switch leap-a-day \
> - leapcrash set-tai set-2038 set-tz rtctest_setdate
> + leapcrash set-tai set-2038 set-tz rtctest_setdate \
> + rtctest-2038
>
>
> include ../lib.mk
> @@ -29,4 +30,5 @@ run_destructive_tests: run_tests
> ./set-tz
> ./set-tai
> ./set-2038
> + ./rtctest-2038
>
> diff --git a/tools/testing/selftests/timers/rtctest-2038.c b/tools/testing/selftests/timers/rtctest-2038.c
> new file mode 100644
> index 0000000..213b7ee
> --- /dev/null
> +++ b/tools/testing/selftests/timers/rtctest-2038.c
> @@ -0,0 +1,135 @@
> +/* Real Time Clock Driver Test
> + * by: Benjamin Gaignard ([email protected])
> + *
> + * To build
> + * gcc rtctest-2038.c -o rtctest-2038
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <stdio.h>
> +#include <linux/rtc.h>
> +#include <sys/ioctl.h>
> +#include <sys/time.h>
> +#include <sys/types.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +
> +static const char default_rtc[] = "/dev/rtc0";
> +
> +int main(int argc, char **argv)
> +{
> + int fd, retval;
> + struct rtc_time new, current;
> + const char *rtc = default_rtc;
> +
> + switch (argc) {
> + case 2:
> + rtc = argv[1];
> + /* FALLTHROUGH */
> + case 1:
> + break;
> + default:
> + fprintf(stderr, "usage: rtctest-2038 [rtcdev]\n");
> + return 1;
> + }
> +
> + fprintf(stderr, "\nTest if RTC is robust for date after y2038/2106\n\n");
> +
> + fd = open(rtc, O_RDONLY);
> + if (fd == -1) {
> + perror(rtc);
> + exit(errno);
> + }
> +
> + new.tm_year = 300; /* 2200 - 1900 */
It would be nice to have tests for 1900, 1901, 1969, 1970, 2037,
2038, 2099, 2100, 2105, 2106, 2261 and 2262.
Those are the various cutoff dates that exist and RTC supporting up to
2099 are certainly more common that RTC handling dates after 2200 else,
most RTC will fail the test.
> + new.tm_mon = 0;
> + new.tm_mday = 1;
> + new.tm_hour = 0;
> + new.tm_min = 0;
> + new.tm_sec = 0;
> +
> + fprintf(stderr, "Test will set RTC date/time to %d-%d-%d, %02d:%02d:%02d.\n",
> + new.tm_mday, new.tm_mon + 1, new.tm_year + 1900,
> + new.tm_hour, new.tm_min, new.tm_sec);
> +
> + /* Write the new date in RTC */
> + retval = ioctl(fd, RTC_SET_TIME, &new);
> + if (retval == -1) {
> + perror("RTC_SET_TIME ioctl");
> + close(fd);
> + exit(errno);
> + }
> +
> + /* Read back */
> + retval = ioctl(fd, RTC_RD_TIME, ¤t);
> + if (retval == -1) {
> + perror("RTC_RD_TIME ioctl");
> + exit(errno);
> + }
> +
> + fprintf(stderr, "RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
> + current.tm_mday, current.tm_mon + 1, current.tm_year + 1900,
> + current.tm_hour, current.tm_min, current.tm_sec);
> +
> + if (new.tm_year != current.tm_year ||
> + new.tm_mon != current.tm_mon ||
> + new.tm_mday != current.tm_mday ||
> + new.tm_hour != current.tm_hour ||
> + new.tm_min != current.tm_min ||
> + new.tm_sec != current.tm_sec) {
This may fail because nothing guarantees that the RTC will reset its
sub seconds counter to 0 when setting the time so new.tm_sec could be
current.tm_sec + 1.
Maybe you could factorize the comparison in a function.
Finally, I won't insist on that but it could be interesting to integrate
it in rtctest.c, hidden behind a option warning that it is "destructive"
(i.e. the current time and date will be lost).
> + fprintf(stderr, "\n\nSet Time test failed\n");
> + close(fd);
> + return 1;
> + }
> +
> + new.tm_sec += 5;
> +
> + fprintf(stderr, "\nTest will set RTC alarm to %d-%d-%d, %02d:%02d:%02d.\n",
> + new.tm_mday, new.tm_mon + 1, new.tm_year + 1900,
> + new.tm_hour, new.tm_min, new.tm_sec);
> +
> + /* Write the new alarm in RTC */
> + retval = ioctl(fd, RTC_ALM_SET, &new);
> + if (retval == -1) {
> + perror("RTC_ALM_SET ioctl");
> + close(fd);
> + exit(errno);
> + }
> +
> + /* Read back */
> + retval = ioctl(fd, RTC_ALM_READ, ¤t);
> + if (retval == -1) {
> + perror("RTC_ALM_READ ioctl");
> + exit(errno);
> + }
> +
> + fprintf(stderr, "RTC alarm is %d-%d-%d, %02d:%02d:%02d.\n",
> + current.tm_mday, current.tm_mon + 1, current.tm_year + 1900,
> + current.tm_hour, current.tm_min, current.tm_sec);
> +
> + if (new.tm_year != current.tm_year ||
> + new.tm_mon != current.tm_mon ||
> + new.tm_mday != current.tm_mday ||
> + new.tm_hour != current.tm_hour ||
> + new.tm_min != current.tm_min ||
> + new.tm_sec != current.tm_sec) {
> + fprintf(stderr, "\n\nSet alarm test failed\n");
> + close(fd);
> + return 1;
> + }
> +
> + fprintf(stderr, "\nTest complete\n");
> + close(fd);
> + return 0;
> +}
> --
> 1.9.1
>
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
Hi Benjamin
On 06/16/2017 04:03 PM, Benjamin Gaignard wrote:
> Make driver use u64 variables and functions to be sure that
> it will support dates after year 2038.
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> drivers/rtc/rtc-st-lpc.c | 19 ++++++++-----------
> 1 file changed, 8 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
> index 74c0a33..82b0af1 100644
> --- a/drivers/rtc/rtc-st-lpc.c
> +++ b/drivers/rtc/rtc-st-lpc.c
> @@ -99,7 +99,7 @@ static int st_rtc_read_time(struct device *dev, struct rtc_time *tm)
>
> lpt = ((unsigned long long)lpt_msb << 32) | lpt_lsb;
> do_div(lpt, rtc->clkrate);
> - rtc_time_to_tm(lpt, tm);
> + rtc_time64_to_tm(lpt, tm);
>
> return 0;
> }
> @@ -107,13 +107,10 @@ static int st_rtc_read_time(struct device *dev, struct rtc_time *tm)
> static int st_rtc_set_time(struct device *dev, struct rtc_time *tm)
> {
> struct st_rtc *rtc = dev_get_drvdata(dev);
> - unsigned long long lpt;
> - unsigned long secs, flags;
> - int ret;
> + unsigned long long lpt, secs;
> + unsigned long flags;
>
> - ret = rtc_tm_to_time(tm, &secs);
> - if (ret)
> - return ret;
> + secs = rtc_tm_to_time64(tm);
>
> lpt = (unsigned long long)secs * rtc->clkrate;
>
> @@ -161,13 +158,13 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
> {
> struct st_rtc *rtc = dev_get_drvdata(dev);
> struct rtc_time now;
> - unsigned long now_secs;
> - unsigned long alarm_secs;
> + unsigned long long now_secs;
> + unsigned long long alarm_secs;
> unsigned long long lpa;
>
> st_rtc_read_time(dev, &now);
> - rtc_tm_to_time(&now, &now_secs);
> - rtc_tm_to_time(&t->time, &alarm_secs);
> + now_secs = rtc_tm_to_time64(&now);
> + alarm_secs = rtc_tm_to_time64(&t->time);
>
> /* Invalid alarm time */
> if (now_secs > alarm_secs)
>
Acked-by: Patrice Chotard <[email protected]>
Thanks