rtc: factor out RTC_Linux_ReadTime_AfterInterrupt

We have code to read time after an RTC's UIE interrupt, which we
currently use as part of maintaining the correction file.

In a later commit, we will need the same functionality for using the RTC
as reference clock, so export the function and give it a descriptive
name appropriate for a globally visible function.
This commit is contained in:
Ahmad Fatoum 2024-07-17 13:00:39 +02:00
parent d1b7878781
commit 577cf09bc5
2 changed files with 33 additions and 21 deletions

View file

@ -785,43 +785,53 @@ RTC_Linux_CheckInterrupt(int fd)
return (data & RTC_UF) == RTC_UF; return (data & RTC_UF) == RTC_UF;
} }
time_t
RTC_Linux_ReadTime_AfterInterrupt(int fd, int utc, struct timespec *sys_time_cooked)
{
int status;
struct rtc_time rtc_raw;
/* Read RTC time, sandwiched between two polls of the system clock
so we can bound any error. */
SCH_GetLastEventTime(sys_time_cooked, NULL, NULL);
status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
if (status < 0) {
LOG(LOGS_ERR, "Could not read time from %s : %s", CNF_GetRtcDevice(), strerror(errno));
return -1;
}
/* Convert RTC time into a struct timespec */
return t_from_rtc(&rtc_raw, utc);
}
static void static void
read_from_device(int fd_, int event, void *any) read_from_device(int fd_, int event, void *any)
{ {
int status; int status;
struct timespec sys_time; struct timespec sys_time;
struct rtc_time rtc_raw;
time_t rtc_t; time_t rtc_t;
int error = 0; int error = 0;
status = RTC_Linux_CheckInterrupt(fd); status = RTC_Linux_CheckInterrupt(fd);
if (status < 0) { if (status == -1) {
SCH_RemoveFileHandler(fd); SCH_RemoveFileHandler(fd);
RTC_Linux_SwitchInterrupt(fd, 0); /* Likely to raise error too, but just to be sure... */ RTC_Linux_SwitchInterrupt(fd, 0); /* Likely to raise error too, but just to be sure... */
close(fd); close(fd);
fd = -1; fd = -1;
return; return;
} else if (status == 0) { } else if (status == 0) {
return; /* Wait for the next interrupt, this one may be bogus */
return;
} }
SCH_GetLastEventTime(&sys_time, NULL, NULL); rtc_t = RTC_Linux_ReadTime_AfterInterrupt(fd, rtc_on_utc, &sys_time);
if (rtc_t == (time_t)-1) {
status = ioctl(fd, RTC_RD_TIME, &rtc_raw);
if (status < 0) {
LOG(LOGS_ERR, "Could not read time from %s : %s", CNF_GetRtcDevice(), strerror(errno));
error = 1; error = 1;
goto turn_off_interrupt; goto turn_off_interrupt;
} }
/* Convert RTC time into a struct timespec */
rtc_t = t_from_rtc(&rtc_raw, rtc_on_utc);
if (rtc_t == (time_t)(-1)) {
error = 1;
goto turn_off_interrupt;
}
process_reading(rtc_t, &sys_time); process_reading(rtc_t, &sys_time);
if (n_samples < 4) { if (n_samples < 4) {

View file

@ -44,5 +44,7 @@ extern void RTC_Linux_CycleLogFile(void);
extern int RTC_Linux_SwitchInterrupt(int fd, int on_off); extern int RTC_Linux_SwitchInterrupt(int fd, int on_off);
extern int RTC_Linux_CheckInterrupt(int fd); extern int RTC_Linux_CheckInterrupt(int fd);
extern time_t RTC_Linux_ReadTime_AfterInterrupt(int fd, int utc,
struct timespec *sys_time_cooked);
#endif /* _GOT_RTC_LINUX_H */ #endif /* _GOT_RTC_LINUX_H */