Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 1 | /* rtc-test.c |
| 2 | * |
| 3 | * Tests for the Real Time Clock driver. |
| 4 | * |
| 5 | * Copyright (c) Larsen & Toubro Infotech Ltd., 2010 |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 6 | * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 7 | * |
| 8 | * Author : Silesh C V <Silesh.Vellattu@lntinfotech.com> |
| 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by |
| 12 | * the Free Software Foundation; either version 2 of the License, or |
| 13 | * (at your option) any later version. |
| 14 | * |
| 15 | * This program is distributed in the hope that it will be useful, |
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
| 18 | * the GNU General Public License for more details. |
| 19 | * |
| 20 | * You should have received a copy of the GNU General Public License |
| 21 | * along with this program; if not, write to the Free Software |
Wanlong Gao | 4548c6c | 2012-10-19 18:03:36 +0800 | [diff] [blame] | 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 23 | */ |
| 24 | |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 25 | |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 26 | #include <sys/ioctl.h> |
| 27 | #include <stdio.h> |
| 28 | #include <stdlib.h> |
| 29 | #include <fcntl.h> |
| 30 | #include <unistd.h> |
| 31 | #include <linux/rtc.h> |
| 32 | #include <errno.h> |
| 33 | #include <time.h> |
| 34 | |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 35 | #include "test.h" |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 36 | |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 37 | int rtc_fd = -1; |
| 38 | char *TCID = "rtc01"; |
| 39 | int TST_TOTAL = 3; |
| 40 | |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 41 | static char *rtc_dev = "/dev/rtc"; |
| 42 | static int dflag; |
| 43 | static const option_t options[] = { |
| 44 | {"d:", &dflag, &rtc_dev}, |
| 45 | {NULL, NULL, NULL} |
| 46 | }; |
| 47 | |
| 48 | static void help(void) |
| 49 | { |
| 50 | printf(" -d x rtc device node, default is %s\n", |
| 51 | rtc_dev); |
| 52 | } |
| 53 | |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 54 | /* Read and Alarm Tests : Read test reads the Date/time from RTC |
| 55 | * while Alarm test, sets the alarm to 5 seconds in future and |
| 56 | * waits for it to ring.The ioctls tested in these tests are |
| 57 | * RTC_RD_TIME, RTC_ALM_SET, RTC_ALM_READ, RTC_AIE_OFF */ |
| 58 | |
| 59 | void read_alarm_test(void) |
| 60 | { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 61 | struct rtc_time rtc_tm; |
| 62 | int ret; |
| 63 | unsigned long data; |
| 64 | fd_set rfds; |
| 65 | struct timeval tv; |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 66 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 67 | tst_resm(TINFO, "RTC READ TEST:"); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 68 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 69 | /*Read RTC Time */ |
| 70 | ret = ioctl(rtc_fd, RTC_RD_TIME, &rtc_tm); |
| 71 | if (ret == -1) { |
| 72 | tst_resm(TFAIL, "RTC_RD_TIME ioctl failed"); |
| 73 | return; |
| 74 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 75 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 76 | tst_resm(TPASS, "RTC READ TEST Passed"); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 77 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 78 | tst_resm(TINFO, "Current RTC date/time is %d-%d-%d, %02d:%02d:%02d.", |
| 79 | rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900, |
| 80 | rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 81 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 82 | tst_resm(TINFO, "RTC ALARM TEST :"); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 83 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 84 | /*set Alarm to 5 Seconds */ |
| 85 | rtc_tm.tm_sec += 5; |
| 86 | if (rtc_tm.tm_sec >= 60) { |
| 87 | rtc_tm.tm_sec %= 60; |
| 88 | rtc_tm.tm_min++; |
| 89 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 90 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 91 | if (rtc_tm.tm_min == 60) { |
| 92 | rtc_tm.tm_min = 0; |
| 93 | rtc_tm.tm_hour++; |
| 94 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 95 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 96 | if (rtc_tm.tm_hour == 24) |
| 97 | rtc_tm.tm_hour = 0; |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 98 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 99 | ret = ioctl(rtc_fd, RTC_ALM_SET, &rtc_tm); |
| 100 | if (ret == -1) { |
| 101 | tst_resm(TFAIL, "RTC_ALM_SET ioctl failed"); |
| 102 | return; |
| 103 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 104 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 105 | /*Read current alarm time */ |
| 106 | ret = ioctl(rtc_fd, RTC_ALM_READ, &rtc_tm); |
| 107 | if (ret == -1) { |
| 108 | tst_resm(TFAIL, "RTC_ALM_READ ioctl failed"); |
| 109 | return; |
| 110 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 111 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 112 | tst_resm(TINFO, "Alarm time set to %02d:%02d:%02d.", |
| 113 | rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); |
| 114 | /* Enable alarm interrupts */ |
| 115 | ret = ioctl(rtc_fd, RTC_AIE_ON, 0); |
| 116 | if (ret == -1) { |
| 117 | tst_resm(TINFO, "RTC_AIE_ON ioctl failed"); |
| 118 | return; |
| 119 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 120 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 121 | tst_resm(TINFO, "Waiting 5 seconds for the alarm..."); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 122 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 123 | tv.tv_sec = 6; /*set 6 seconds as the time out */ |
| 124 | tv.tv_usec = 0; |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 125 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 126 | FD_ZERO(&rfds); |
| 127 | FD_SET(rtc_fd, &rfds); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 128 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 129 | ret = select(rtc_fd + 1, &rfds, NULL, NULL, &tv); /*wait for alarm */ |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 130 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 131 | if (ret == -1) { |
| 132 | tst_resm(TFAIL, "select failed"); |
| 133 | return; |
| 134 | } else if (ret) { |
| 135 | ret = read(rtc_fd, &data, sizeof(unsigned long)); |
| 136 | if (ret == -1) { |
| 137 | tst_resm(TFAIL, "read failed"); |
| 138 | return; |
| 139 | } |
| 140 | tst_resm(TINFO, "Alarm rang."); |
| 141 | } else { |
| 142 | tst_resm(TFAIL, "Timed out waiting for the alarm"); |
| 143 | return; |
| 144 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 145 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 146 | /* Disable alarm interrupts */ |
| 147 | ret = ioctl(rtc_fd, RTC_AIE_OFF, 0); |
| 148 | if (ret == -1) { |
| 149 | tst_resm(TFAIL, "RTC_AIE_OFF ioctl failed"); |
| 150 | return; |
| 151 | } |
| 152 | tst_resm(TPASS, "RTC ALARM TEST Passed"); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 153 | } |
| 154 | |
| 155 | /* Update_interrupts_test :Once the Update interrupts is enabled, |
| 156 | * the RTC gives interrupts (1/sec) on the interrupts line(if the rtc |
| 157 | * has one). This is tested by enabling the update interrupts |
| 158 | * and then waiting for 5 interrupts.*/ |
| 159 | |
| 160 | void update_interrupts_test(void) |
| 161 | { |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 162 | int ret, i; |
| 163 | unsigned long data; |
| 164 | fd_set rfds; |
| 165 | struct timeval tv; |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 166 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 167 | tst_resm(TINFO, "RTC UPDATE INTERRUPTS TEST :"); |
| 168 | /*Turn on update interrupts */ |
| 169 | ret = ioctl(rtc_fd, RTC_UIE_ON, 0); |
| 170 | if (ret == -1) { |
| 171 | tst_resm(TFAIL, "RTC_UIE_ON ioctl failed"); |
| 172 | return; |
| 173 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 174 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 175 | tst_resm(TINFO, "Waiting for 5 update interrupts..."); |
| 176 | for (i = 1; i < 6; i++) { |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 177 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 178 | tv.tv_sec = 2; /*2 sec time out for each interrupt */ |
| 179 | tv.tv_usec = 0; |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 180 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 181 | FD_ZERO(&rfds); |
| 182 | FD_SET(rtc_fd, &rfds); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 183 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 184 | ret = select(rtc_fd + 1, &rfds, NULL, NULL, &tv); |
| 185 | if (ret == -1) { |
| 186 | tst_resm(TFAIL, "select failed"); |
| 187 | return; |
| 188 | } else if (ret) { |
| 189 | ret = read(rtc_fd, &data, sizeof(unsigned long)); |
| 190 | if (ret == -1) { |
| 191 | tst_resm(TFAIL, "read failed"); |
| 192 | return; |
| 193 | } |
| 194 | tst_resm(TINFO, "Update interrupt %d", i); |
| 195 | } else { |
| 196 | tst_resm(TFAIL, |
| 197 | "Timed out waiting for the update interrupt"); |
| 198 | return; |
| 199 | } |
| 200 | } |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 201 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 202 | /* Turn off update interrupts */ |
| 203 | ret = ioctl(rtc_fd, RTC_UIE_OFF, 0); |
| 204 | if (ret == -1) { |
| 205 | tst_resm(TFAIL, "RTC_UIE_OFF ioctl failed"); |
| 206 | return; |
| 207 | } |
| 208 | tst_resm(TPASS, "RTC UPDATE INTERRUPTS TEST Passed"); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 209 | } |
| 210 | |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 211 | int main(int argc, char *argv[]) |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 212 | { |
Cyril Hrubis | 0b9589f | 2014-05-27 17:40:33 +0200 | [diff] [blame] | 213 | const char *msg; |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 214 | msg = parse_opts(argc, argv, options, help); |
| 215 | if (msg != NULL) |
| 216 | tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 217 | |
Alexey Kodanev | 473b8cf | 2013-09-09 16:23:01 +0400 | [diff] [blame] | 218 | tst_require_root(NULL); |
| 219 | |
| 220 | if (access(rtc_dev, F_OK) == -1) |
| 221 | tst_brkm(TCONF, NULL, "couldn't find rtc device '%s'", rtc_dev); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 222 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 223 | rtc_fd = open(rtc_dev, O_RDONLY); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 224 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 225 | if (rtc_fd < 0) |
| 226 | tst_brkm(TBROK | TERRNO, NULL, "couldn't open %s", rtc_dev); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 227 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 228 | /*Read and alarm tests */ |
| 229 | read_alarm_test(); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 230 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 231 | /*Update interrupts test */ |
| 232 | update_interrupts_test(); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 233 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 234 | close(rtc_fd); |
Rishikesh K Rajak | e7ed287 | 2010-03-22 10:42:05 +0530 | [diff] [blame] | 235 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 236 | tst_resm(TINFO, "RTC Tests Done!"); |
| 237 | tst_exit(); |
Chris Dearman | ec6edca | 2012-10-17 19:54:01 -0700 | [diff] [blame] | 238 | } |