diff options
author | Stefan Eichenberger <stefan.eichenberger@toradex.com> | 2022-11-03 16:29:08 +0100 |
---|---|---|
committer | Francesco Dolcini <francesco.dolcini@toradex.com> | 2022-11-09 17:34:03 +0000 |
commit | 7fa95acb6fdcc61bd128183f19c47e51eafcbc6b (patch) | |
tree | 9bb66de2e833dc4f86409c7254ef4af358c4f879 | |
parent | b6a453bdcd4841f44dc6c86f2abd06fe97936580 (diff) |
linux-toradex-mainline: Add patch to fix an RTC issue appearing on iMX6ULL
This is a fix for an issue with the RTC on the Colibri iMX6ULL. The
issue can be triggered as follows:
echo 0 > /sys/class/rtc/rtc1/wakealarm
rtc rtc1: Timeout trying to get valid LPSRT Counter read
Related-to: ELB-4814
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
-rw-r--r-- | recipes-kernel/linux/linux-toradex-mainline-git/0001-rtc-snvs-Allow-a-time-difference-on-clock-register-r.patch | 84 | ||||
-rw-r--r-- | recipes-kernel/linux/linux-toradex-mainline_git.bb | 1 |
2 files changed, 85 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-toradex-mainline-git/0001-rtc-snvs-Allow-a-time-difference-on-clock-register-r.patch b/recipes-kernel/linux/linux-toradex-mainline-git/0001-rtc-snvs-Allow-a-time-difference-on-clock-register-r.patch new file mode 100644 index 0000000..5f7e6e9 --- /dev/null +++ b/recipes-kernel/linux/linux-toradex-mainline-git/0001-rtc-snvs-Allow-a-time-difference-on-clock-register-r.patch @@ -0,0 +1,84 @@ +From 97bddda523427274f0fb45971a5d33407449a054 Mon Sep 17 00:00:00 2001 +From: Stefan Eichenberger <stefan.eichenberger@toradex.com> +Date: Wed, 2 Nov 2022 13:24:23 +0100 +Subject: [PATCH] rtc: snvs: Allow a time difference on clock register read + +On an iMX6ULL the following message appears when a wakealarm is set: + +echo 0 > /sys/class/rtc/rtc1/wakealarm +rtc rtc1: Timeout trying to get valid LPSRT Counter read + +This does not always happen but is reproducible quite often (7 out of 10 +times). The problem appears because the iMX6ULL is not able to read the +registers within one 32kHz clock cycle which is the base clock of the +RTC. Therefore, this patch allows a difference of up to 320 cycles +(10ms). 10ms was chosen to be big enough even on systems with less cpu +power (e.g. iMX6ULL). According to the reference manual a difference is +fine: +- If the two consecutive reads are similar, the value is correct. +The values have to be similar, not equal. + +Upstream-Status: Submitted [https://lore.kernel.org/linux-rtc/20221106115915.7930-1-francesco@dolcini.it] +Fixes: cd7f3a249dbe ("rtc: snvs: Add timeouts to avoid kernel lockups") +Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com> +--- + drivers/rtc/rtc-snvs.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c +index bd929b0e7d7de..d82acf1af1fae 100644 +--- a/drivers/rtc/rtc-snvs.c ++++ b/drivers/rtc/rtc-snvs.c +@@ -32,6 +32,14 @@ + #define SNVS_LPPGDR_INIT 0x41736166 + #define CNTR_TO_SECS_SH 15 + ++/* The maximum RTC clock cycles that are allowed to pass between two ++ * consecutive clock counter register reads. If the values are corrupted a ++ * bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles ++ * we end at 10ms which should be enough for most cases. If it once takes ++ * longer than expected we do a retry. ++ */ ++#define MAX_RTC_READ_DIFF_CYCLES 320 ++ + struct snvs_rtc_data { + struct rtc_device *rtc; + struct regmap *regmap; +@@ -56,6 +64,7 @@ static u64 rtc_read_lpsrt(struct snvs_rtc_data *data) + static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) + { + u64 read1, read2; ++ s64 diff; + unsigned int timeout = 100; + + /* As expected, the registers might update between the read of the LSB +@@ -66,7 +75,8 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) + do { + read2 = read1; + read1 = rtc_read_lpsrt(data); +- } while (read1 != read2 && --timeout); ++ diff = read1 - read2; ++ } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); + if (!timeout) + dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); + +@@ -78,13 +88,15 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) + static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb) + { + u32 count1, count2; ++ s32 diff; + unsigned int timeout = 100; + + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); + do { + count2 = count1; + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); +- } while (count1 != count2 && --timeout); ++ diff = count1 - count2; ++ } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); + if (!timeout) { + dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); + return -ETIMEDOUT; +-- +2.34.1 + diff --git a/recipes-kernel/linux/linux-toradex-mainline_git.bb b/recipes-kernel/linux/linux-toradex-mainline_git.bb index e066e62..6fdc488 100644 --- a/recipes-kernel/linux/linux-toradex-mainline_git.bb +++ b/recipes-kernel/linux/linux-toradex-mainline_git.bb @@ -35,6 +35,7 @@ SRC_URI:append = " \ file://0002-arm-dts-colibri-imx6ull-enable-default-peripherals.patch \ file://0001-ARM-dts-colibri-imx6ull-Enable-dual-role-switching.patch \ file://0002-drivers-chipidea-disable-runtime-pm-for-imx6ul.patch \ + file://0001-rtc-snvs-Allow-a-time-difference-on-clock-register-r.patch \ " LINUX_VERSION ?= "6.0.6" |