Repository navigation
rtc: hibvt: judge the time by its counter, not the low-voltage flag - #81
openipc-ai merged 2 commits into
Conversation
|
/review |
Code Review by Qodo
1. Valid clocks become unreadable after 2106
|
|
/review |
|
Code review by qodo was updated up to the latest commit afbd139 |
Port of the hisilicon-hi3516ev200 fix. This branch's copy kept the vendor's handling of the backup supply low-voltage flag: read_time() logs "low voltage detected" and returns -EINVAL whenever the flag is set. The flag is "cleared" by writing 1 to RTC_INT_CLR, though, and that is the alarm bit. So once the flag is set it never clears, every read fails and logs an error, and the RTC stays unreadable. The flag is not a reliable verdict anyway. On a hi3516ev300 it stays set, and returns about 0.5 s after each correct clear, with a fresh backup cell that keeps the time through a 5-minute power cut. - Do not fail the read, or log, because of the flag. Clear it with LV_INT_MASK. - Judge the time by the counter: return -EINVAL for a value before 2000-01-01, which is what a counter that lost power reads. set_time() refuses the same range, so every time it accepts can be read back.
afbd139 to
083acb3
Compare
set_time() collected the SPI write results in an unsigned char, so a bridge timeout (-EIO) came back as 251: RTC_SET_TIME reported success for a write that never reached the RTC. Every other function here already uses int.
|
/review |
|
Code review by qodo was updated up to the latest commit 0e9e3dd |
… counter (#125) arm: dts: hi3516cv300: let rtc-hibvt bind the RTC The RTC node said "hisilicon,hi_rtc", which no in-tree driver matches. rtc-hibvt matches "hisilicon,hi35xx-rtc" and drives the same block (SPI bridge at 0x12090000, the same register map as the SDK's hi3516cv300 RTC module), so with CONFIG_RTC_DRV_HIBVT the board still had no /dev/rtc0. That is OpenIPC/firmware#191: hwclock has no RTC to open, and the SDK module only offers private HI_RTC_* ioctls, so pointing /dev/rtc0 at it fails with EPERM. rtc: hibvt: judge the time by its counter, and leave hi3516cv300's CL… …K_CFG alone Port of the hisilicon-hi3536dv100 change (#81), which this branch's copy of the driver matches byte for byte: - read_time() no longer fails, or logs, because of the low-voltage flag. The flag was "cleared" by writing 1 to RTC_INT_CLR, which is the alarm bit, so once set it never cleared and the RTC stayed unreadable. It is not a verdict on the time anyway: on a hi3516ev300 it stays set with a backup cell that keeps the time. - A counter before 2000-01-01, which is what a counter that lost power reads, is reported as unset, so hctosys does not set the clock to 1970. set_time() refuses the same range. - The flag is cleared with LV_INT_MASK. On hi3516cv300, skip the RTC_CLK_CFG write. The SDK's own hi3516cv300 RTC driver never writes it, and it reads 0 on a running board; the 0x01 here is the hi3536cv100 value. rtc: hibvt: return set_time()'s SPI errors as errors set_time() collected the SPI write results in an unsigned char, so a bridge timeout (-EIO) came back as 251: RTC_SET_TIME reported success for a write that never reached the RTC. Every other function here already uses int.
Port of #79 (hisilicon-hi3516ev200) to hisilicon-hi3536dv100. Read #79 for the analysis and the hardware results.
This branch's copy differs from #79 in one way that matters. It kept the vendor's handling:
read_time()logslow voltage detected, date/time is not reliableand returns-EINVALwhenever the backup supply low-voltage flag is set. The flag is "cleared" by writing1toRTC_INT_CLR, though, and that is the alarm bit. So once the flag is set it never clears, every read fails and logs an error, and the RTC stays unreadable.The flag is not a reliable verdict either. On the hi3516ev300 in #79 it stays set, and returns about 0.5 s after each correct clear, with a fresh backup cell that keeps the time through a 5-minute power cut. A board like that would have a working RTC that this driver refuses to read.
Change (the same as #79)
LV_INT_MASK.-EINVALfor a value before 2000-01-01, which is what a counter that lost power reads.set_time()refuses the same range, so every time it accepts can be read back (Qodo's first point).Qodo's second point, that init could clear the flag before it was reported, no longer applies: nothing reports the flag.
Verification
hi3536dv100.generic.config(CONFIG_ARCH_HI3536DV100=y).hi3536dv100_lite, RTC at120b0000.rtc). I built this branch'srtc-hibvt.cas an out-of-tree module with the driver renamed tohibvt_rtc_test, unbound the built-in driver, and loaded the module in its place:The built-in driver was bound again afterwards.
With the driver built in, on the same board. I built
hi3536dv100_lite's kernel with Buildroot, changed onlyrtc-hibvt.c, and U-Boot loaded it over TFTP for the test. The NORkernelpartition was never written. Afterwards the board went back to its stock kernel and original environment.Cold boot after an 8 s power cut through a switchable plug (the board stopped answering ping during the cut). This board has backup power, and the time was applied with no message:
Counter zeroed, then
reboot -f. The counter is refused at boot, and userspace restores the clock:set_time()andread_time()agree:Not reproducible here: this board's low-voltage flag is clear (
RTC_INT_RAWreads0), so the old driver's refusal to read while the flag is set couldn't be shown on it. The flag behaviour comes from the hi3516ev300 in #79.Review fix:
set_time()errorshibvt_rtc_set_time()collected the SPI write results in anunsigned char, so a bridge timeout (-EIO) came back as251, andRTC_SET_TIMEreported success for a write that never reached the RTC (Qodo). It is now anint, like every other function in the file.The SPI timeout can't be triggered on demand, so the error path itself is covered only by the type fix. The same file, with the same fix, was re-run on a hi3516cv300 in #125: setting the time returns
0, 1999 is refused, and the time reads back. The lab hi3536dv100 was off the network for this round, so it was not re-run there.