Skip to content

Commit 2a027d6

Browse files
jjang417shuahkh
authored andcommitted
selftest: rtc: Add to check rtc alarm status for alarm related test
In alarm_wkalm_set and alarm_wkalm_set_minute test, they use different ioctl (RTC_ALM_SET/RTC_WKALM_SET) for alarm feature detection. They will skip testing if RTC_ALM_SET/RTC_WKALM_SET ioctl returns an EINVAL error code. This design may miss detecting real problems when the efi.set_wakeup_time() return errors and then RTC_ALM_SET/RTC_WKALM_SET ioctl returns an EINVAL error code with RTC_FEATURE_ALARM enabled. In order to make rtctest more explicit and robust, we propose to use RTC_PARAM_GET ioctl interface to check rtc alarm feature state before running alarm related tests. If the kernel does not support RTC_PARAM_GET ioctl interface, we will fallback to check the error number of (RTC_ALM_SET/RTC_WKALM_SET) ioctl call for alarm feature detection. Requires commit 101ca8d ("rtc: efi: Enable SET/GET WAKEUP services as optional") Reviewed-by: Koba Ko <kobak@nvidia.com> Reviewed-by: Matthew R. Ochs <mochs@nvidia.com> Signed-off-by: Joseph Jang <jjang@nvidia.com> Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
1 parent ecfe687 commit 2a027d6

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

tools/testing/selftests/rtc/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
2-
CFLAGS += -O3 -Wl,-no-as-needed -Wall
2+
CFLAGS += -O3 -Wl,-no-as-needed -Wall -I$(top_srcdir)/usr/include
33
LDLIBS += -lrt -lpthread -lm
44

55
TEST_GEN_PROGS = rtctest

tools/testing/selftests/rtc/rtctest.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525

2626
static char *rtc_file = "/dev/rtc0";
2727

28+
enum rtc_alarm_state {
29+
RTC_ALARM_UNKNOWN,
30+
RTC_ALARM_ENABLED,
31+
RTC_ALARM_DISABLED,
32+
};
33+
2834
FIXTURE(rtc) {
2935
int fd;
3036
};
@@ -82,6 +88,24 @@ static void nanosleep_with_retries(long ns)
8288
}
8389
}
8490

91+
static enum rtc_alarm_state get_rtc_alarm_state(int fd)
92+
{
93+
struct rtc_param param = { 0 };
94+
int rc;
95+
96+
/* Validate kernel reflects unsupported RTC alarm state */
97+
param.param = RTC_PARAM_FEATURES;
98+
param.index = 0;
99+
rc = ioctl(fd, RTC_PARAM_GET, &param);
100+
if (rc < 0)
101+
return RTC_ALARM_UNKNOWN;
102+
103+
if ((param.uvalue & _BITUL(RTC_FEATURE_ALARM)) == 0)
104+
return RTC_ALARM_DISABLED;
105+
106+
return RTC_ALARM_ENABLED;
107+
}
108+
85109
TEST_F_TIMEOUT(rtc, date_read_loop, READ_LOOP_DURATION_SEC + 2) {
86110
int rc;
87111
long iter_count = 0;
@@ -197,11 +221,16 @@ TEST_F(rtc, alarm_alm_set) {
197221
fd_set readfds;
198222
time_t secs, new;
199223
int rc;
224+
enum rtc_alarm_state alarm_state = RTC_ALARM_UNKNOWN;
200225

201226
if (self->fd == -1 && errno == ENOENT)
202227
SKIP(return, "Skipping test since %s does not exist", rtc_file);
203228
ASSERT_NE(-1, self->fd);
204229

230+
alarm_state = get_rtc_alarm_state(self->fd);
231+
if (alarm_state == RTC_ALARM_DISABLED)
232+
SKIP(return, "Skipping test since alarms are not supported.");
233+
205234
rc = ioctl(self->fd, RTC_RD_TIME, &tm);
206235
ASSERT_NE(-1, rc);
207236

@@ -210,6 +239,11 @@ TEST_F(rtc, alarm_alm_set) {
210239

211240
rc = ioctl(self->fd, RTC_ALM_SET, &tm);
212241
if (rc == -1) {
242+
/*
243+
* Report error if rtc alarm was enabled. Fallback to check ioctl
244+
* error number if rtc alarm state is unknown.
245+
*/
246+
ASSERT_EQ(RTC_ALARM_UNKNOWN, alarm_state);
213247
ASSERT_EQ(EINVAL, errno);
214248
TH_LOG("skip alarms are not supported.");
215249
return;
@@ -255,11 +289,16 @@ TEST_F(rtc, alarm_wkalm_set) {
255289
fd_set readfds;
256290
time_t secs, new;
257291
int rc;
292+
enum rtc_alarm_state alarm_state = RTC_ALARM_UNKNOWN;
258293

259294
if (self->fd == -1 && errno == ENOENT)
260295
SKIP(return, "Skipping test since %s does not exist", rtc_file);
261296
ASSERT_NE(-1, self->fd);
262297

298+
alarm_state = get_rtc_alarm_state(self->fd);
299+
if (alarm_state == RTC_ALARM_DISABLED)
300+
SKIP(return, "Skipping test since alarms are not supported.");
301+
263302
rc = ioctl(self->fd, RTC_RD_TIME, &alarm.time);
264303
ASSERT_NE(-1, rc);
265304

@@ -270,6 +309,11 @@ TEST_F(rtc, alarm_wkalm_set) {
270309

271310
rc = ioctl(self->fd, RTC_WKALM_SET, &alarm);
272311
if (rc == -1) {
312+
/*
313+
* Report error if rtc alarm was enabled. Fallback to check ioctl
314+
* error number if rtc alarm state is unknown.
315+
*/
316+
ASSERT_EQ(RTC_ALARM_UNKNOWN, alarm_state);
273317
ASSERT_EQ(EINVAL, errno);
274318
TH_LOG("skip alarms are not supported.");
275319
return;
@@ -307,11 +351,16 @@ TEST_F_TIMEOUT(rtc, alarm_alm_set_minute, 65) {
307351
fd_set readfds;
308352
time_t secs, new;
309353
int rc;
354+
enum rtc_alarm_state alarm_state = RTC_ALARM_UNKNOWN;
310355

311356
if (self->fd == -1 && errno == ENOENT)
312357
SKIP(return, "Skipping test since %s does not exist", rtc_file);
313358
ASSERT_NE(-1, self->fd);
314359

360+
alarm_state = get_rtc_alarm_state(self->fd);
361+
if (alarm_state == RTC_ALARM_DISABLED)
362+
SKIP(return, "Skipping test since alarms are not supported.");
363+
315364
rc = ioctl(self->fd, RTC_RD_TIME, &tm);
316365
ASSERT_NE(-1, rc);
317366

@@ -320,6 +369,11 @@ TEST_F_TIMEOUT(rtc, alarm_alm_set_minute, 65) {
320369

321370
rc = ioctl(self->fd, RTC_ALM_SET, &tm);
322371
if (rc == -1) {
372+
/*
373+
* Report error if rtc alarm was enabled. Fallback to check ioctl
374+
* error number if rtc alarm state is unknown.
375+
*/
376+
ASSERT_EQ(RTC_ALARM_UNKNOWN, alarm_state);
323377
ASSERT_EQ(EINVAL, errno);
324378
TH_LOG("skip alarms are not supported.");
325379
return;
@@ -365,11 +419,16 @@ TEST_F_TIMEOUT(rtc, alarm_wkalm_set_minute, 65) {
365419
fd_set readfds;
366420
time_t secs, new;
367421
int rc;
422+
enum rtc_alarm_state alarm_state = RTC_ALARM_UNKNOWN;
368423

369424
if (self->fd == -1 && errno == ENOENT)
370425
SKIP(return, "Skipping test since %s does not exist", rtc_file);
371426
ASSERT_NE(-1, self->fd);
372427

428+
alarm_state = get_rtc_alarm_state(self->fd);
429+
if (alarm_state == RTC_ALARM_DISABLED)
430+
SKIP(return, "Skipping test since alarms are not supported.");
431+
373432
rc = ioctl(self->fd, RTC_RD_TIME, &alarm.time);
374433
ASSERT_NE(-1, rc);
375434

@@ -380,6 +439,11 @@ TEST_F_TIMEOUT(rtc, alarm_wkalm_set_minute, 65) {
380439

381440
rc = ioctl(self->fd, RTC_WKALM_SET, &alarm);
382441
if (rc == -1) {
442+
/*
443+
* Report error if rtc alarm was enabled. Fallback to check ioctl
444+
* error number if rtc alarm state is unknown.
445+
*/
446+
ASSERT_EQ(RTC_ALARM_UNKNOWN, alarm_state);
383447
ASSERT_EQ(EINVAL, errno);
384448
TH_LOG("skip alarms are not supported.");
385449
return;

0 commit comments

Comments
 (0)