Hello,
this is a followup to https://lore.kernel.org/stable/cover.1749223334.git.u.kleine-koenig@baylibre... that handled backporting the two patches by Alexandre to the active stable kernels between 6.15 and 5.15. Here comes a backport to 5.10.y, git am handles application to 5.4.y just fine.
Compared to the backport for later kernels I included a major rework of rtc_time64_to_tm() by Cassio Neri. (FTR: I checked, that commit by Cassio Neri isn't the reason we need to fix rtc_time64_to_tm(), the actual problem is older.)
Now that I completed the backport and did some final checks on it I noticed that the problem fixed here is (TTBOMK) a theoretic one because only drivers with .start_secs < 0 are known to have issues and in 5.10 and before there is no such driver. I'm uncertain if this should result in not backporting the changes. I would tend to pick them anyhow, but I won't argue on a veto.
Best regards Uwe
Alexandre Mergnat (2): rtc: Make rtc_time64_to_tm() support dates before 1970 rtc: Fix offset calculation for .start_secs < 0
Cassio Neri (1): rtc: Improve performance of rtc_time64_to_tm(). Add tests.
drivers/rtc/Kconfig | 10 ++++ drivers/rtc/Makefile | 1 + drivers/rtc/class.c | 2 +- drivers/rtc/lib.c | 121 ++++++++++++++++++++++++++++++++--------- drivers/rtc/lib_test.c | 79 +++++++++++++++++++++++++++ 5 files changed, 185 insertions(+), 28 deletions(-) create mode 100644 drivers/rtc/lib_test.c
base-commit: 01e7e36b8606e5d4fddf795938010f7bfa3aa277
From: Cassio Neri cassio.neri@gmail.com
commit 1d1bb12a8b1805ddeef9793ebeb920179fb0fa38 upstream.
The current implementation of rtc_time64_to_tm() contains unnecessary loops, branches and look-up tables. The new one uses an arithmetic-based algorithm appeared in [1] and is approximately 4.3 times faster (YMMV).
The drawback is that the new code isn't intuitive and contains many 'magic numbers' (not unusual for this type of algorithm). However, [1] justifies all those numbers and, given this function's history, the code is unlikely to need much maintenance, if any at all.
Add a KUnit test case that checks every day in a 160,000 years interval starting on 1970-01-01 against the expected result. Add a new config RTC_LIB_KUNIT_TEST symbol to give the option to run this test suite.
[1] Neri, Schneider, "Euclidean Affine Functions and Applications to Calendar Algorithms". https://arxiv.org/abs/2102.06959
Signed-off-by: Cassio Neri cassio.neri@gmail.com Reported-by: kernel test robot lkp@intel.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210624201343.85441-1-cassio.neri@gmail.com Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com --- drivers/rtc/Kconfig | 10 ++++ drivers/rtc/Makefile | 1 + drivers/rtc/lib.c | 103 +++++++++++++++++++++++++++++++---------- drivers/rtc/lib_test.c | 79 +++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 25 deletions(-) create mode 100644 drivers/rtc/lib_test.c
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8ddd334e049e..6a4aa5abe366 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -10,6 +10,16 @@ config RTC_MC146818_LIB bool select RTC_LIB
+config RTC_LIB_KUNIT_TEST + tristate "KUnit test for RTC lib functions" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + select RTC_LIB + help + Enable this option to test RTC library functions. + + If unsure, say N. + menuconfig RTC_CLASS bool "Real Time Clock" default n diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index bfb57464118d..03ab2329a0e2 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -183,3 +183,4 @@ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o +obj-$(CONFIG_RTC_LIB_KUNIT_TEST) += lib_test.o diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c index 23284580df97..fe361652727a 100644 --- a/drivers/rtc/lib.c +++ b/drivers/rtc/lib.c @@ -6,6 +6,8 @@ * Author: Alessandro Zummo a.zummo@towertech.it * * based on arch/arm/common/rtctime.c and other bits + * + * Author: Cassio Neri cassio.neri@gmail.com (rtc_time64_to_tm) */
#include <linux/export.h> @@ -22,8 +24,6 @@ static const unsigned short rtc_ydays[2][13] = { { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } };
-#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) - /* * The number of days in the month. */ @@ -42,42 +42,95 @@ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) } EXPORT_SYMBOL(rtc_year_days);
-/* - * rtc_time64_to_tm - Converts time64_t to rtc_time. - * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. +/** + * rtc_time64_to_tm - converts time64_t to rtc_time. + * + * @time: The number of seconds since 01-01-1970 00:00:00. + * (Must be positive.) + * @tm: Pointer to the struct rtc_time. */ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { - unsigned int month, year, secs; + unsigned int secs; int days;
+ u64 u64tmp; + u32 u32tmp, udays, century, day_of_century, year_of_century, year, + day_of_year, month, day; + bool is_Jan_or_Feb, is_leap_year; + /* time must be positive */ days = div_s64_rem(time, 86400, &secs);
/* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7;
- year = 1970 + days / 365; - days -= (year - 1970) * 365 - + LEAPS_THRU_END_OF(year - 1) - - LEAPS_THRU_END_OF(1970 - 1); - while (days < 0) { - year -= 1; - days += 365 + is_leap_year(year); - } - tm->tm_year = year - 1900; - tm->tm_yday = days + 1; + /* + * The following algorithm is, basically, Proposition 6.3 of Neri + * and Schneider [1]. In a few words: it works on the computational + * (fictitious) calendar where the year starts in March, month = 2 + * (*), and finishes in February, month = 13. This calendar is + * mathematically convenient because the day of the year does not + * depend on whether the year is leap or not. For instance: + * + * March 1st 0-th day of the year; + * ... + * April 1st 31-st day of the year; + * ... + * January 1st 306-th day of the year; (Important!) + * ... + * February 28th 364-th day of the year; + * February 29th 365-th day of the year (if it exists). + * + * After having worked out the date in the computational calendar + * (using just arithmetics) it's easy to convert it to the + * corresponding date in the Gregorian calendar. + * + * [1] "Euclidean Affine Functions and Applications to Calendar + * Algorithms". https://arxiv.org/abs/2102.06959 + * + * (*) The numbering of months follows rtc_time more closely and + * thus, is slightly different from [1]. + */
- for (month = 0; month < 11; month++) { - int newdays; + udays = ((u32) days) + 719468;
- newdays = days - rtc_month_days(month, year); - if (newdays < 0) - break; - days = newdays; - } - tm->tm_mon = month; - tm->tm_mday = days + 1; + u32tmp = 4 * udays + 3; + century = u32tmp / 146097; + day_of_century = u32tmp % 146097 / 4; + + u32tmp = 4 * day_of_century + 3; + u64tmp = 2939745ULL * u32tmp; + year_of_century = upper_32_bits(u64tmp); + day_of_year = lower_32_bits(u64tmp) / 2939745 / 4; + + year = 100 * century + year_of_century; + is_leap_year = year_of_century != 0 ? + year_of_century % 4 == 0 : century % 4 == 0; + + u32tmp = 2141 * day_of_year + 132377; + month = u32tmp >> 16; + day = ((u16) u32tmp) / 2141; + + /* + * Recall that January 01 is the 306-th day of the year in the + * computational (not Gregorian) calendar. + */ + is_Jan_or_Feb = day_of_year >= 306; + + /* Converts to the Gregorian calendar. */ + year = year + is_Jan_or_Feb; + month = is_Jan_or_Feb ? month - 12 : month; + day = day + 1; + + day_of_year = is_Jan_or_Feb ? + day_of_year - 306 : day_of_year + 31 + 28 + is_leap_year; + + /* Converts to rtc_time's format. */ + tm->tm_year = (int) (year - 1900); + tm->tm_mon = (int) month; + tm->tm_mday = (int) day; + tm->tm_yday = (int) day_of_year + 1;
tm->tm_hour = secs / 3600; secs -= tm->tm_hour * 3600; diff --git a/drivers/rtc/lib_test.c b/drivers/rtc/lib_test.c new file mode 100644 index 000000000000..2124b67a2f43 --- /dev/null +++ b/drivers/rtc/lib_test.c @@ -0,0 +1,79 @@ +// 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) +{ + if (*mday != rtc_month_days(*month - 1, *year)) { + ++*mday; + ++*yday; + return; + } + + *mday = 1; + if (*month != 12) { + ++*month; + ++*yday; + return; + } + + *month = 1; + *yday = 1; + ++*year; +} + +/* + * Checks every day in a 160000 years interval starting on 1970-01-01 + * against the expected result. + */ +static void rtc_time64_to_tm_test_date_range(struct kunit *test) +{ + /* + * 160000 years = (160000 / 400) * 400 years + * = (160000 / 400) * 146097 days + * = (160000 / 400) * 146097 * 86400 seconds + */ + time64_t total_secs = ((time64_t) 160000) / 400 * 146097 * 86400; + + int year = 1970; + int month = 1; + int mday = 1; + int yday = 1; + + struct rtc_time result; + time64_t secs; + s64 days; + + for (secs = 0; secs <= total_secs; secs += 86400) { + + rtc_time64_to_tm(secs, &result); + + days = div_s64(secs, 86400); + + #define FAIL_MSG "%d/%02d/%02d (%2d) : %ld", \ + year, month, mday, yday, days + + 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); + + advance_date(&year, &month, &mday, &yday); + } +} + +static struct kunit_case rtc_lib_test_cases[] = { + KUNIT_CASE(rtc_time64_to_tm_test_date_range), + {} +}; + +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);
[ Sasha's backport helper bot ]
Hi,
Summary of potential issues: ⚠️ Found follow-up fixes in mainline
The upstream commit SHA1 provided is correct: 1d1bb12a8b1805ddeef9793ebeb920179fb0fa38
WARNING: Author mismatch between patch and upstream commit: Backport author: u.kleine-koenig@baylibre.com Commit author: Cassio Nericassio.neri@gmail.com
Status in newer kernel trees: 6.15.y | Present (exact SHA1) 6.14.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (exact SHA1) 6.1.y | Present (exact SHA1) 5.15.y | Present (exact SHA1)
Found fixes commits: 8a904a3caa88 rtc: test: Fix invalid format specifier.
Note: The patch differs from the upstream commit: --- 1: 1d1bb12a8b180 ! 1: b0856f15968b7 rtc: Improve performance of rtc_time64_to_tm(). Add tests. @@ Metadata ## Commit message ## rtc: Improve performance of rtc_time64_to_tm(). Add tests.
+ commit 1d1bb12a8b1805ddeef9793ebeb920179fb0fa38 upstream. + The current implementation of rtc_time64_to_tm() contains unnecessary loops, branches and look-up tables. The new one uses an arithmetic-based algorithm appeared in [1] and is approximately 4.3 times faster (YMMV). @@ Commit message Reported-by: kernel test robot lkp@intel.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210624201343.85441-1-cassio.neri@gmail.com + Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com
## drivers/rtc/Kconfig ## @@ drivers/rtc/Kconfig: config RTC_MC146818_LIB ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.10.y | Success | Success |
From: Alexandre Mergnat amergnat@baylibre.com
commit 7df4cfef8b351fec3156160bedfc7d6d29de4cce upstream.
Conversion of dates before 1970 is still relevant today because these dates are reused on some hardwares to store dates bigger than the maximal date that is representable in the device's native format. This prominently and very soon affects the hardware covered by the rtc-mt6397 driver that can only natively store dates in the interval 1900-01-01 up to 2027-12-31. So to store the date 2028-01-01 00:00:00 to such a device, rtc_time64_to_tm() must do the right thing for time=-2208988800.
Signed-off-by: Alexandre Mergnat amergnat@baylibre.com Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-1-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com --- drivers/rtc/lib.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c index fe361652727a..13b5b1f20465 100644 --- a/drivers/rtc/lib.c +++ b/drivers/rtc/lib.c @@ -46,24 +46,38 @@ EXPORT_SYMBOL(rtc_year_days); * rtc_time64_to_tm - converts time64_t to rtc_time. * * @time: The number of seconds since 01-01-1970 00:00:00. - * (Must be positive.) + * Works for values since at least 1900 * @tm: Pointer to the struct rtc_time. */ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { - unsigned int secs; - int days; + int days, secs;
u64 u64tmp; u32 u32tmp, udays, century, day_of_century, year_of_century, year, day_of_year, month, day; bool is_Jan_or_Feb, is_leap_year;
- /* time must be positive */ + /* + * Get days and seconds while preserving the sign to + * handle negative time values (dates before 1970-01-01) + */ days = div_s64_rem(time, 86400, &secs);
+ /* + * We need 0 <= secs < 86400 which isn't given for negative + * values of time. Fixup accordingly. + */ + if (secs < 0) { + days -= 1; + secs += 86400; + } + /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; + /* Ensure tm_wday is always positive */ + if (tm->tm_wday < 0) + tm->tm_wday += 7;
/* * The following algorithm is, basically, Proposition 6.3 of Neri @@ -93,7 +107,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) * thus, is slightly different from [1]. */
- udays = ((u32) days) + 719468; + udays = days + 719468;
u32tmp = 4 * udays + 3; century = u32tmp / 146097;
Hi all,
Although untested, I'm pretty sure that with very small changes, the previous revision (1d1bb12) can handle dates prior to 1970-01-01 with no need to add extra branches or arithmetic operations. Indeed, 1d1bb12 contains:
<code> /* time must be positive */ days = div_s64_rem(time, 86400, &secs);
/* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7;
/* long comments */
udays = ((u32) days) + 719468; </code>
This could have been changed to:
<code> /* time must be >= -719468 * 86400 which corresponds to 0000-03-01 */ udays = div_u64_rem(time + 719468 * 86400, 86400, &secs);
/* day of the week, 0000-03-01 was a Wednesday (in the proleptic Gregorian calendar) */ tm->tm_wday = (days + 3) % 7;
/* long comments */ </code>
Indeed, the addition of 719468 * 86400 to `time` makes `days` to be 719468 more than it should be. Therefore, in the calculation of `udays`, the addition of 719468 becomes unnecessary and thus, `udays == days`. Moreover, this means that `days` can be removed altogether and replaced by `udays`. (Not the other way around because in the remaining code `udays` must be u32.)
Now, 719468 % 7 = 1 and thus tm->wday is 1 day after what it should be and we correct that by adding 3 instead of 4.
Therefore, I suggest these changes on top of 1d1bb12 instead of those made in 7df4cfe. Since you're working on this, can I please kindly suggest two other changes?
1) Change the reference provided in the long comment. It should say, "The following algorithm is, basically, Figure 12 of Neri and Schneider [1]" and [1] should refer to the published article:
Neri C, Schneider L. Euclidean affine functions and their application to calendar algorithms. Softw Pract Exper. 2023;53(4):937-970. doi: 10.1002/spe.3172 https://doi.org/10.1002/spe.3172
The article is much better written and clearer than the pre-print currently referred to.
2) Function rtc_time64_to_tm_test_date_range in drivers/rtc/lib_test.c, is a kunit test that checks the result for everyday in a 160000 years range starting at 1970-01-01. It'd be nice if this test is adapted to the new code and starts at 1900-01-01 (technically, it could start at 0000-03-01 but since tm->year counts from 1900, it would be weird to see tm->year == -1900 to mean that the calendar year is 0.) Also 160000 is definitely an overkill (my bad!) and a couple of thousands of years, say 3000, should be more than safe for anyone. :-)
Many thanks, Cassio.
On Tue, 10 Jun 2025 at 08:35, Uwe Kleine-König u.kleine-koenig@baylibre.com wrote:
From: Alexandre Mergnat amergnat@baylibre.com
commit 7df4cfef8b351fec3156160bedfc7d6d29de4cce upstream.
Conversion of dates before 1970 is still relevant today because these dates are reused on some hardwares to store dates bigger than the maximal date that is representable in the device's native format. This prominently and very soon affects the hardware covered by the rtc-mt6397 driver that can only natively store dates in the interval 1900-01-01 up to 2027-12-31. So to store the date 2028-01-01 00:00:00 to such a device, rtc_time64_to_tm() must do the right thing for time=-2208988800.
Signed-off-by: Alexandre Mergnat amergnat@baylibre.com Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-1-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com
drivers/rtc/lib.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c index fe361652727a..13b5b1f20465 100644 --- a/drivers/rtc/lib.c +++ b/drivers/rtc/lib.c @@ -46,24 +46,38 @@ EXPORT_SYMBOL(rtc_year_days);
- rtc_time64_to_tm - converts time64_t to rtc_time.
- @time: The number of seconds since 01-01-1970 00:00:00.
(Must be positive.)
*/
Works for values since at least 1900
- @tm: Pointer to the struct rtc_time.
void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) {
unsigned int secs;
int days;
int days, secs; u64 u64tmp; u32 u32tmp, udays, century, day_of_century, year_of_century, year, day_of_year, month, day; bool is_Jan_or_Feb, is_leap_year;
/* time must be positive */
/*
* Get days and seconds while preserving the sign to
* handle negative time values (dates before 1970-01-01)
*/ days = div_s64_rem(time, 86400, &secs);
/*
* We need 0 <= secs < 86400 which isn't given for negative
* values of time. Fixup accordingly.
*/
if (secs < 0) {
days -= 1;
secs += 86400;
}
/* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7;
/* Ensure tm_wday is always positive */
if (tm->tm_wday < 0)
tm->tm_wday += 7; /* * The following algorithm is, basically, Proposition 6.3 of Neri
@@ -93,7 +107,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) * thus, is slightly different from [1]. */
udays = ((u32) days) + 719468;
udays = days + 719468; u32tmp = 4 * udays + 3; century = u32tmp / 146097;
-- 2.49.0
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 7df4cfef8b351fec3156160bedfc7d6d29de4cce
WARNING: Author mismatch between patch and upstream commit: Backport author: u.kleine-koenig@baylibre.com Commit author: Alexandre Mergnatamergnat@baylibre.com
Status in newer kernel trees: 6.15.y | Present (different SHA1: aa9745977724) 6.14.y | Present (different SHA1: 1fd85fd8b7ba) 6.12.y | Present (different SHA1: a6a55fe660f8) 6.6.y | Present (different SHA1: 9af5a32330f8) 6.1.y | Present (different SHA1: 75cd3ea1caef) 5.15.y | Present (different SHA1: fc02a9de9a12)
Note: The patch differs from the upstream commit: --- 1: 7df4cfef8b351 ! 1: c046d6497bd0a rtc: Make rtc_time64_to_tm() support dates before 1970 @@ Metadata ## Commit message ## rtc: Make rtc_time64_to_tm() support dates before 1970
+ commit 7df4cfef8b351fec3156160bedfc7d6d29de4cce upstream. + Conversion of dates before 1970 is still relevant today because these dates are reused on some hardwares to store dates bigger than the maximal date that is representable in the device's native format. @@ Commit message Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-1-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com + Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com
## drivers/rtc/lib.c ## @@ drivers/rtc/lib.c: EXPORT_SYMBOL(rtc_year_days); ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.15.y | Success | Success |
From: Alexandre Mergnat amergnat@baylibre.com
commit fe9f5f96cfe8b82d0f24cbfa93718925560f4f8d upstream.
The comparison
rtc->start_secs > rtc->range_max
has a signed left-hand side and an unsigned right-hand side. So the comparison might become true for negative start_secs which is interpreted as a (possibly very large) positive value.
As a negative value can never be bigger than an unsigned value the correct representation of the (mathematical) comparison
rtc->start_secs > rtc->range_max
in C is:
rtc->start_secs >= 0 && rtc->start_secs > rtc->range_max
Use that to fix the offset calculation currently used in the rtc-mt6397 driver.
Fixes: 989515647e783 ("rtc: Add one offset seconds to expand RTC range") Signed-off-by: Alexandre Mergnat amergnat@baylibre.com Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-2-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com --- drivers/rtc/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 625effe6cb65..b1ce3bd724b2 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -314,7 +314,7 @@ static void rtc_device_get_offset(struct rtc_device *rtc) * * Otherwise the offset seconds should be 0. */ - if (rtc->start_secs > rtc->range_max || + if ((rtc->start_secs >= 0 && rtc->start_secs > rtc->range_max) || rtc->start_secs + range_secs - 1 < rtc->range_min) rtc->offset_secs = rtc->start_secs - rtc->range_min; else if (rtc->start_secs > rtc->range_min)
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: fe9f5f96cfe8b82d0f24cbfa93718925560f4f8d
WARNING: Author mismatch between patch and upstream commit: Backport author: u.kleine-koenig@baylibre.com Commit author: Alexandre Mergnatamergnat@baylibre.com
Status in newer kernel trees: 6.15.y | Present (different SHA1: cea549ca705b) 6.14.y | Present (different SHA1: 57082e0300d5) 6.12.y | Present (different SHA1: 6b482b16f32e) 6.6.y | Present (different SHA1: 3d8efdcbc6ce) 6.1.y | Present (different SHA1: b2677da58ed4) 5.15.y | Present (different SHA1: 0931dc7be5dd)
Note: The patch differs from the upstream commit: --- 1: fe9f5f96cfe8b ! 1: 8aa260951391e rtc: Fix offset calculation for .start_secs < 0 @@ Metadata ## Commit message ## rtc: Fix offset calculation for .start_secs < 0
+ commit fe9f5f96cfe8b82d0f24cbfa93718925560f4f8d upstream. + The comparison
rtc->start_secs > rtc->range_max @@ Commit message Reviewed-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Link: https://lore.kernel.org/r/20250428-enable-rtc-v4-2-2b2f7e3f9349@baylibre.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com + Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com
## drivers/rtc/class.c ## @@ drivers/rtc/class.c: static void rtc_device_get_offset(struct rtc_device *rtc) ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.15.y | Success | Success |
linux-stable-mirror@lists.linaro.org