summaryrefslogtreecommitdiff
path: root/drivers/rtc/test_rtc_lib.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-08-03 20:17:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2025-08-03 20:17:34 -0700
commitd2eedaa3909be9102d648a4a0a50ccf64f96c54f (patch)
tree9d35227946a17335c506cdad95a83d69dfdc0e97 /drivers/rtc/test_rtc_lib.c
parent806381e1a24c6eec2b431cbba2ba1b81e518fea8 (diff)
parentbb5b0b4317c9516bdc5e9a4235e3b5f1a73b7e48 (diff)
Merge tag 'rtc-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linuxHEADmaster
Pull RTC updates from Alexandre Belloni: "Support for a new RTC in an existing driver and all the drivers exposing clocks using the common clock framework have been converted to determine_rate(). Summary: Subsystem: - Convert drivers exposing a clock from round_rate() to determine_rate() Drivers: - ds1307: oscillator stop flag handling for ds1341 - pcf85063: add support for RV8063" * tag 'rtc-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (34 commits) rtc: ds1685: Update Joshua Kinard's email address. rtc: rv3032: convert from round_rate() to determine_rate() rtc: rv3028: convert from round_rate() to determine_rate() rtc: pcf8563: convert from round_rate() to determine_rate() rtc: pcf85063: convert from round_rate() to determine_rate() rtc: nct3018y: convert from round_rate() to determine_rate() rtc: max31335: convert from round_rate() to determine_rate() rtc: m41t80: convert from round_rate() to determine_rate() rtc: hym8563: convert from round_rate() to determine_rate() rtc: ds1307: convert from round_rate() to determine_rate() rtc: rv3028: fix incorrect maximum clock rate handling rtc: pcf8563: fix incorrect maximum clock rate handling rtc: pcf85063: fix incorrect maximum clock rate handling rtc: nct3018y: fix incorrect maximum clock rate handling rtc: hym8563: fix incorrect maximum clock rate handling rtc: ds1307: fix incorrect maximum clock rate handling rtc: pcf85063: scope pcf85063_config structures rtc: Optimize calculations in rtc_time64_to_tm() dt-bindings: rtc: amlogic,a4-rtc: Add compatible string for C3 rtc: ds1307: handle oscillator stop flag (OSF) for ds1341 ...
Diffstat (limited to 'drivers/rtc/test_rtc_lib.c')
-rw-r--r--drivers/rtc/test_rtc_lib.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/drivers/rtc/test_rtc_lib.c b/drivers/rtc/test_rtc_lib.c
new file mode 100644
index 000000000000..0eebad1fe2a0
--- /dev/null
+++ b/drivers/rtc/test_rtc_lib.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: LGPL-2.1+
+
+#include <kunit/test.h>
+#include <linux/rtc.h>
+
+/*
+ * Advance a date by one day.
+ */
+static void advance_date(int *year, int *month, int *mday, int *yday, int *wday)
+{
+ *wday = (*wday + 1) % 7;
+
+ if (*mday != rtc_month_days(*month - 1, *year)) {
+ ++*mday;
+ ++*yday;
+ return;
+ }
+
+ *mday = 1;
+ if (*month != 12) {
+ ++*month;
+ ++*yday;
+ return;
+ }
+
+ *month = 1;
+ *yday = 1;
+ ++*year;
+}
+
+/*
+ * Check every day in specified number of years interval starting on 1970-01-01
+ * against the expected result.
+ */
+static void rtc_time64_to_tm_test_date_range(struct kunit *test, int years)
+{
+ /*
+ * years = (years / 400) * 400 years
+ * = (years / 400) * 146097 days
+ * = (years / 400) * 146097 * 86400 seconds
+ */
+ time64_t total_secs = ((time64_t)years) / 400 * 146097 * 86400;
+
+ int year = 1900;
+ int month = 1;
+ int mday = 1;
+ int yday = 1;
+ int wday = 1; /* Jan 1st 1900 was a Monday */
+
+ struct rtc_time result;
+ time64_t secs;
+ const time64_t sec_offset = RTC_TIMESTAMP_BEGIN_1900 + ((1 * 60) + 2) * 60 + 3;
+
+ for (secs = 0; secs <= total_secs; secs += 86400) {
+
+ rtc_time64_to_tm(secs + sec_offset, &result);
+
+ #define FAIL_MSG "%d/%02d/%02d (%2d, %d) : %lld", \
+ year, month, mday, yday, wday, secs + sec_offset
+
+ KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG);
+ KUNIT_ASSERT_EQ_MSG(test, month - 1, result.tm_mon, FAIL_MSG);
+ KUNIT_ASSERT_EQ_MSG(test, mday, result.tm_mday, FAIL_MSG);
+ KUNIT_ASSERT_EQ_MSG(test, yday, result.tm_yday, FAIL_MSG);
+ KUNIT_ASSERT_EQ_MSG(test, 1, result.tm_hour, FAIL_MSG);
+ KUNIT_ASSERT_EQ_MSG(test, 2, result.tm_min, FAIL_MSG);
+ KUNIT_ASSERT_EQ_MSG(test, 3, result.tm_sec, FAIL_MSG);
+ KUNIT_ASSERT_EQ_MSG(test, wday, result.tm_wday, FAIL_MSG);
+
+ advance_date(&year, &month, &mday, &yday, &wday);
+ }
+}
+
+/*
+ * Checks every day in a 160000 years interval starting on 1900-01-01
+ * against the expected result.
+ */
+static void rtc_time64_to_tm_test_date_range_160000(struct kunit *test)
+{
+ rtc_time64_to_tm_test_date_range(test, 160000);
+}
+
+/*
+ * Checks every day in a 1000 years interval starting on 1900-01-01
+ * against the expected result.
+ */
+static void rtc_time64_to_tm_test_date_range_1000(struct kunit *test)
+{
+ rtc_time64_to_tm_test_date_range(test, 1000);
+}
+
+static struct kunit_case rtc_lib_test_cases[] = {
+ KUNIT_CASE(rtc_time64_to_tm_test_date_range_1000),
+ KUNIT_CASE_SLOW(rtc_time64_to_tm_test_date_range_160000),
+ {}
+};
+
+static struct kunit_suite rtc_lib_test_suite = {
+ .name = "rtc_lib_test_cases",
+ .test_cases = rtc_lib_test_cases,
+};
+
+kunit_test_suite(rtc_lib_test_suite);
+
+MODULE_DESCRIPTION("KUnit test for RTC lib functions");
+MODULE_LICENSE("GPL");