Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: rtc: rtctest: add alarm test on minute boundary

Unfortunately, some RTC don't have a second resolution for alarm so also
test for alarm on a minute boundary.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Shuah Khan <shuah@kernel.org>

authored by

Alexandre Belloni and committed by
Shuah Khan
7b302772 fdac9448

+102
+102
tools/testing/selftests/rtc/rtctest.c
··· 211 211 ASSERT_EQ(new, secs); 212 212 } 213 213 214 + TEST_F(rtc, alarm_alm_set_minute) { 215 + struct timeval tv = { .tv_sec = 62 }; 216 + unsigned long data; 217 + struct rtc_time tm; 218 + fd_set readfds; 219 + time_t secs, new; 220 + int rc; 221 + 222 + rc = ioctl(self->fd, RTC_RD_TIME, &tm); 223 + ASSERT_NE(-1, rc); 224 + 225 + secs = timegm((struct tm *)&tm) + 60 - tm.tm_sec; 226 + gmtime_r(&secs, (struct tm *)&tm); 227 + 228 + rc = ioctl(self->fd, RTC_ALM_SET, &tm); 229 + if (rc == -1) { 230 + ASSERT_EQ(EINVAL, errno); 231 + TH_LOG("skip alarms are not supported."); 232 + return; 233 + } 234 + 235 + rc = ioctl(self->fd, RTC_ALM_READ, &tm); 236 + ASSERT_NE(-1, rc); 237 + 238 + TH_LOG("Alarm time now set to %02d:%02d:%02d.", 239 + tm.tm_hour, tm.tm_min, tm.tm_sec); 240 + 241 + /* Enable alarm interrupts */ 242 + rc = ioctl(self->fd, RTC_AIE_ON, 0); 243 + ASSERT_NE(-1, rc); 244 + 245 + FD_ZERO(&readfds); 246 + FD_SET(self->fd, &readfds); 247 + 248 + rc = select(self->fd + 1, &readfds, NULL, NULL, &tv); 249 + ASSERT_NE(-1, rc); 250 + ASSERT_NE(0, rc); 251 + 252 + /* Disable alarm interrupts */ 253 + rc = ioctl(self->fd, RTC_AIE_OFF, 0); 254 + ASSERT_NE(-1, rc); 255 + 256 + rc = read(self->fd, &data, sizeof(unsigned long)); 257 + ASSERT_NE(-1, rc); 258 + TH_LOG("data: %lx", data); 259 + 260 + rc = ioctl(self->fd, RTC_RD_TIME, &tm); 261 + ASSERT_NE(-1, rc); 262 + 263 + new = timegm((struct tm *)&tm); 264 + ASSERT_EQ(new, secs); 265 + } 266 + 267 + TEST_F(rtc, alarm_wkalm_set_minute) { 268 + struct timeval tv = { .tv_sec = 62 }; 269 + struct rtc_wkalrm alarm = { 0 }; 270 + struct rtc_time tm; 271 + unsigned long data; 272 + fd_set readfds; 273 + time_t secs, new; 274 + int rc; 275 + 276 + rc = ioctl(self->fd, RTC_RD_TIME, &alarm.time); 277 + ASSERT_NE(-1, rc); 278 + 279 + secs = timegm((struct tm *)&alarm.time) + 60 - alarm.time.tm_sec; 280 + gmtime_r(&secs, (struct tm *)&alarm.time); 281 + 282 + alarm.enabled = 1; 283 + 284 + rc = ioctl(self->fd, RTC_WKALM_SET, &alarm); 285 + if (rc == -1) { 286 + ASSERT_EQ(EINVAL, errno); 287 + TH_LOG("skip alarms are not supported."); 288 + return; 289 + } 290 + 291 + rc = ioctl(self->fd, RTC_WKALM_RD, &alarm); 292 + ASSERT_NE(-1, rc); 293 + 294 + TH_LOG("Alarm time now set to %02d/%02d/%02d %02d:%02d:%02d.", 295 + alarm.time.tm_mday, alarm.time.tm_mon + 1, 296 + alarm.time.tm_year + 1900, alarm.time.tm_hour, 297 + alarm.time.tm_min, alarm.time.tm_sec); 298 + 299 + FD_ZERO(&readfds); 300 + FD_SET(self->fd, &readfds); 301 + 302 + rc = select(self->fd + 1, &readfds, NULL, NULL, &tv); 303 + ASSERT_NE(-1, rc); 304 + ASSERT_NE(0, rc); 305 + 306 + rc = read(self->fd, &data, sizeof(unsigned long)); 307 + ASSERT_NE(-1, rc); 308 + 309 + rc = ioctl(self->fd, RTC_RD_TIME, &tm); 310 + ASSERT_NE(-1, rc); 311 + 312 + new = timegm((struct tm *)&tm); 313 + ASSERT_EQ(new, secs); 314 + } 315 + 214 316 static void __attribute__((constructor)) 215 317 __constructor_order_last(void) 216 318 {