aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2015-03-23 16:32:09 -0400
committerShuah Khan <shuahkh@osg.samsung.com>2015-03-25 00:01:58 -0400
commit4a5fd81507eaea556e533e9ebc8a3cf31fe159d1 (patch)
tree21b26a2c6983d79c77f893dfde6961943287d840 /tools/testing
parentf901caaf8e45c7917029ec9197622f0167ea2d40 (diff)
Documentation, split up rtc.txt into documentation and test file
This patch splits rtc.txt into two separate files, one for the documentation itself, and the other for the rtctest.c file. The rtctest file is moved into the kernel tools/testing/selftests/timers directory. This will make automated testing easier. Note that the only difference in the rtc.txt file is that the location of the rtctest.c file has changed. Signed-off-by: Prarit Bhargava <prarit@redhat.com> Acked-by: Jonathan Corbet <corbet@lwn.net> Acked-by: John Stultz <john.stultz@linaro.org> Cc: corbet@lwn.net Cc: rtc-linux@googlegroups.com Cc: linux-doc@vger.kernel.org Cc: a.zummo@towertech.it Cc: prarit@redhat.com Cc: john.stultz@linaro.org Cc: shuahkh@osg.samsung.com Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Diffstat (limited to 'tools/testing')
-rw-r--r--tools/testing/selftests/timers/Makefile2
-rw-r--r--tools/testing/selftests/timers/rtctest.c258
2 files changed, 259 insertions, 1 deletions
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 670aebdb4a99..89a3f44bf355 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -6,7 +6,7 @@ LDFLAGS += -lrt -lpthread
6# these are all "safe" tests that don't modify 6# these are all "safe" tests that don't modify
7# system time or require escalated privledges 7# system time or require escalated privledges
8TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ 8TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
9 inconsistency-check raw_skew threadtest 9 inconsistency-check raw_skew threadtest rtctest
10 10
11TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex change_skew \ 11TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex change_skew \
12 skew_consistency clocksource-switch leap-a-day \ 12 skew_consistency clocksource-switch leap-a-day \
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c
new file mode 100644
index 000000000000..1e06f4602195
--- /dev/null
+++ b/tools/testing/selftests/timers/rtctest.c
@@ -0,0 +1,258 @@
1/*
2 * Real Time Clock Driver Test/Example Program
3 *
4 * Compile with:
5 * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
6 *
7 * Copyright (C) 1996, Paul Gortmaker.
8 *
9 * Released under the GNU General Public License, version 2,
10 * included herein by reference.
11 *
12 */
13
14#include <stdio.h>
15#include <linux/rtc.h>
16#include <sys/ioctl.h>
17#include <sys/time.h>
18#include <sys/types.h>
19#include <fcntl.h>
20#include <unistd.h>
21#include <stdlib.h>
22#include <errno.h>
23
24
25/*
26 * This expects the new RTC class driver framework, working with
27 * clocks that will often not be clones of what the PC-AT had.
28 * Use the command line to specify another RTC if you need one.
29 */
30static const char default_rtc[] = "/dev/rtc0";
31
32
33int main(int argc, char **argv)
34{
35 int i, fd, retval, irqcount = 0;
36 unsigned long tmp, data;
37 struct rtc_time rtc_tm;
38 const char *rtc = default_rtc;
39
40 switch (argc) {
41 case 2:
42 rtc = argv[1];
43 /* FALLTHROUGH */
44 case 1:
45 break;
46 default:
47 fprintf(stderr, "usage: rtctest [rtcdev]\n");
48 return 1;
49 }
50
51 fd = open(rtc, O_RDONLY);
52
53 if (fd == -1) {
54 perror(rtc);
55 exit(errno);
56 }
57
58 fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");
59
60 /* Turn on update interrupts (one per second) */
61 retval = ioctl(fd, RTC_UIE_ON, 0);
62 if (retval == -1) {
63 if (errno == ENOTTY) {
64 fprintf(stderr,
65 "\n...Update IRQs not supported.\n");
66 goto test_READ;
67 }
68 perror("RTC_UIE_ON ioctl");
69 exit(errno);
70 }
71
72 fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:",
73 rtc);
74 fflush(stderr);
75 for (i=1; i<6; i++) {
76 /* This read will block */
77 retval = read(fd, &data, sizeof(unsigned long));
78 if (retval == -1) {
79 perror("read");
80 exit(errno);
81 }
82 fprintf(stderr, " %d",i);
83 fflush(stderr);
84 irqcount++;
85 }
86
87 fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
88 fflush(stderr);
89 for (i=1; i<6; i++) {
90 struct timeval tv = {5, 0}; /* 5 second timeout on select */
91 fd_set readfds;
92
93 FD_ZERO(&readfds);
94 FD_SET(fd, &readfds);
95 /* The select will wait until an RTC interrupt happens. */
96 retval = select(fd+1, &readfds, NULL, NULL, &tv);
97 if (retval == -1) {
98 perror("select");
99 exit(errno);
100 }
101 /* This read won't block unlike the select-less case above. */
102 retval = read(fd, &data, sizeof(unsigned long));
103 if (retval == -1) {
104 perror("read");
105 exit(errno);
106 }
107 fprintf(stderr, " %d",i);
108 fflush(stderr);
109 irqcount++;
110 }
111
112 /* Turn off update interrupts */
113 retval = ioctl(fd, RTC_UIE_OFF, 0);
114 if (retval == -1) {
115 perror("RTC_UIE_OFF ioctl");
116 exit(errno);
117 }
118
119test_READ:
120 /* Read the RTC time/date */
121 retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
122 if (retval == -1) {
123 perror("RTC_RD_TIME ioctl");
124 exit(errno);
125 }
126
127 fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
128 rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
129 rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
130
131 /* Set the alarm to 5 sec in the future, and check for rollover */
132 rtc_tm.tm_sec += 5;
133 if (rtc_tm.tm_sec >= 60) {
134 rtc_tm.tm_sec %= 60;
135 rtc_tm.tm_min++;
136 }
137 if (rtc_tm.tm_min == 60) {
138 rtc_tm.tm_min = 0;
139 rtc_tm.tm_hour++;
140 }
141 if (rtc_tm.tm_hour == 24)
142 rtc_tm.tm_hour = 0;
143
144 retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
145 if (retval == -1) {
146 if (errno == ENOTTY) {
147 fprintf(stderr,
148 "\n...Alarm IRQs not supported.\n");
149 goto test_PIE;
150 }
151 perror("RTC_ALM_SET ioctl");
152 exit(errno);
153 }
154
155 /* Read the current alarm settings */
156 retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
157 if (retval == -1) {
158 perror("RTC_ALM_READ ioctl");
159 exit(errno);
160 }
161
162 fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
163 rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
164
165 /* Enable alarm interrupts */
166 retval = ioctl(fd, RTC_AIE_ON, 0);
167 if (retval == -1) {
168 perror("RTC_AIE_ON ioctl");
169 exit(errno);
170 }
171
172 fprintf(stderr, "Waiting 5 seconds for alarm...");
173 fflush(stderr);
174 /* This blocks until the alarm ring causes an interrupt */
175 retval = read(fd, &data, sizeof(unsigned long));
176 if (retval == -1) {
177 perror("read");
178 exit(errno);
179 }
180 irqcount++;
181 fprintf(stderr, " okay. Alarm rang.\n");
182
183 /* Disable alarm interrupts */
184 retval = ioctl(fd, RTC_AIE_OFF, 0);
185 if (retval == -1) {
186 perror("RTC_AIE_OFF ioctl");
187 exit(errno);
188 }
189
190test_PIE:
191 /* Read periodic IRQ rate */
192 retval = ioctl(fd, RTC_IRQP_READ, &tmp);
193 if (retval == -1) {
194 /* not all RTCs support periodic IRQs */
195 if (errno == ENOTTY) {
196 fprintf(stderr, "\nNo periodic IRQ support\n");
197 goto done;
198 }
199 perror("RTC_IRQP_READ ioctl");
200 exit(errno);
201 }
202 fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp);
203
204 fprintf(stderr, "Counting 20 interrupts at:");
205 fflush(stderr);
206
207 /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
208 for (tmp=2; tmp<=64; tmp*=2) {
209
210 retval = ioctl(fd, RTC_IRQP_SET, tmp);
211 if (retval == -1) {
212 /* not all RTCs can change their periodic IRQ rate */
213 if (errno == ENOTTY) {
214 fprintf(stderr,
215 "\n...Periodic IRQ rate is fixed\n");
216 goto done;
217 }
218 perror("RTC_IRQP_SET ioctl");
219 exit(errno);
220 }
221
222 fprintf(stderr, "\n%ldHz:\t", tmp);
223 fflush(stderr);
224
225 /* Enable periodic interrupts */
226 retval = ioctl(fd, RTC_PIE_ON, 0);
227 if (retval == -1) {
228 perror("RTC_PIE_ON ioctl");
229 exit(errno);
230 }
231
232 for (i=1; i<21; i++) {
233 /* This blocks */
234 retval = read(fd, &data, sizeof(unsigned long));
235 if (retval == -1) {
236 perror("read");
237 exit(errno);
238 }
239 fprintf(stderr, " %d",i);
240 fflush(stderr);
241 irqcount++;
242 }
243
244 /* Disable periodic interrupts */
245 retval = ioctl(fd, RTC_PIE_OFF, 0);
246 if (retval == -1) {
247 perror("RTC_PIE_OFF ioctl");
248 exit(errno);
249 }
250 }
251
252done:
253 fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
254
255 close(fd);
256
257 return 0;
258}