aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/rtc.txt264
-rw-r--r--tools/testing/selftests/timers/Makefile2
-rw-r--r--tools/testing/selftests/timers/rtctest.c258
3 files changed, 260 insertions, 264 deletions
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 596b60c08b74..8446f1ea1410 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -204,266 +204,4 @@ Some common examples:
204 204
205 * RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code. 205 * RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code.
206 206
207If all else fails, check out the rtc-test.c driver! 207If all else fails, check out the tools/testing/selftests/timers/rtctest.c test!
208
209
210-------------------- 8< ---------------- 8< -----------------------------
211
212/*
213 * Real Time Clock Driver Test/Example Program
214 *
215 * Compile with:
216 * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
217 *
218 * Copyright (C) 1996, Paul Gortmaker.
219 *
220 * Released under the GNU General Public License, version 2,
221 * included herein by reference.
222 *
223 */
224
225#include <stdio.h>
226#include <linux/rtc.h>
227#include <sys/ioctl.h>
228#include <sys/time.h>
229#include <sys/types.h>
230#include <fcntl.h>
231#include <unistd.h>
232#include <stdlib.h>
233#include <errno.h>
234
235
236/*
237 * This expects the new RTC class driver framework, working with
238 * clocks that will often not be clones of what the PC-AT had.
239 * Use the command line to specify another RTC if you need one.
240 */
241static const char default_rtc[] = "/dev/rtc0";
242
243
244int main(int argc, char **argv)
245{
246 int i, fd, retval, irqcount = 0;
247 unsigned long tmp, data;
248 struct rtc_time rtc_tm;
249 const char *rtc = default_rtc;
250
251 switch (argc) {
252 case 2:
253 rtc = argv[1];
254 /* FALLTHROUGH */
255 case 1:
256 break;
257 default:
258 fprintf(stderr, "usage: rtctest [rtcdev]\n");
259 return 1;
260 }
261
262 fd = open(rtc, O_RDONLY);
263
264 if (fd == -1) {
265 perror(rtc);
266 exit(errno);
267 }
268
269 fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");
270
271 /* Turn on update interrupts (one per second) */
272 retval = ioctl(fd, RTC_UIE_ON, 0);
273 if (retval == -1) {
274 if (errno == ENOTTY) {
275 fprintf(stderr,
276 "\n...Update IRQs not supported.\n");
277 goto test_READ;
278 }
279 perror("RTC_UIE_ON ioctl");
280 exit(errno);
281 }
282
283 fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:",
284 rtc);
285 fflush(stderr);
286 for (i=1; i<6; i++) {
287 /* This read will block */
288 retval = read(fd, &data, sizeof(unsigned long));
289 if (retval == -1) {
290 perror("read");
291 exit(errno);
292 }
293 fprintf(stderr, " %d",i);
294 fflush(stderr);
295 irqcount++;
296 }
297
298 fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
299 fflush(stderr);
300 for (i=1; i<6; i++) {
301 struct timeval tv = {5, 0}; /* 5 second timeout on select */
302 fd_set readfds;
303
304 FD_ZERO(&readfds);
305 FD_SET(fd, &readfds);
306 /* The select will wait until an RTC interrupt happens. */
307 retval = select(fd+1, &readfds, NULL, NULL, &tv);
308 if (retval == -1) {
309 perror("select");
310 exit(errno);
311 }
312 /* This read won't block unlike the select-less case above. */
313 retval = read(fd, &data, sizeof(unsigned long));
314 if (retval == -1) {
315 perror("read");
316 exit(errno);
317 }
318 fprintf(stderr, " %d",i);
319 fflush(stderr);
320 irqcount++;
321 }
322
323 /* Turn off update interrupts */
324 retval = ioctl(fd, RTC_UIE_OFF, 0);
325 if (retval == -1) {
326 perror("RTC_UIE_OFF ioctl");
327 exit(errno);
328 }
329
330test_READ:
331 /* Read the RTC time/date */
332 retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
333 if (retval == -1) {
334 perror("RTC_RD_TIME ioctl");
335 exit(errno);
336 }
337
338 fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
339 rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
340 rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
341
342 /* Set the alarm to 5 sec in the future, and check for rollover */
343 rtc_tm.tm_sec += 5;
344 if (rtc_tm.tm_sec >= 60) {
345 rtc_tm.tm_sec %= 60;
346 rtc_tm.tm_min++;
347 }
348 if (rtc_tm.tm_min == 60) {
349 rtc_tm.tm_min = 0;
350 rtc_tm.tm_hour++;
351 }
352 if (rtc_tm.tm_hour == 24)
353 rtc_tm.tm_hour = 0;
354
355 retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
356 if (retval == -1) {
357 if (errno == ENOTTY) {
358 fprintf(stderr,
359 "\n...Alarm IRQs not supported.\n");
360 goto test_PIE;
361 }
362 perror("RTC_ALM_SET ioctl");
363 exit(errno);
364 }
365
366 /* Read the current alarm settings */
367 retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
368 if (retval == -1) {
369 perror("RTC_ALM_READ ioctl");
370 exit(errno);
371 }
372
373 fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
374 rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
375
376 /* Enable alarm interrupts */
377 retval = ioctl(fd, RTC_AIE_ON, 0);
378 if (retval == -1) {
379 perror("RTC_AIE_ON ioctl");
380 exit(errno);
381 }
382
383 fprintf(stderr, "Waiting 5 seconds for alarm...");
384 fflush(stderr);
385 /* This blocks until the alarm ring causes an interrupt */
386 retval = read(fd, &data, sizeof(unsigned long));
387 if (retval == -1) {
388 perror("read");
389 exit(errno);
390 }
391 irqcount++;
392 fprintf(stderr, " okay. Alarm rang.\n");
393
394 /* Disable alarm interrupts */
395 retval = ioctl(fd, RTC_AIE_OFF, 0);
396 if (retval == -1) {
397 perror("RTC_AIE_OFF ioctl");
398 exit(errno);
399 }
400
401test_PIE:
402 /* Read periodic IRQ rate */
403 retval = ioctl(fd, RTC_IRQP_READ, &tmp);
404 if (retval == -1) {
405 /* not all RTCs support periodic IRQs */
406 if (errno == ENOTTY) {
407 fprintf(stderr, "\nNo periodic IRQ support\n");
408 goto done;
409 }
410 perror("RTC_IRQP_READ ioctl");
411 exit(errno);
412 }
413 fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp);
414
415 fprintf(stderr, "Counting 20 interrupts at:");
416 fflush(stderr);
417
418 /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
419 for (tmp=2; tmp<=64; tmp*=2) {
420
421 retval = ioctl(fd, RTC_IRQP_SET, tmp);
422 if (retval == -1) {
423 /* not all RTCs can change their periodic IRQ rate */
424 if (errno == ENOTTY) {
425 fprintf(stderr,
426 "\n...Periodic IRQ rate is fixed\n");
427 goto done;
428 }
429 perror("RTC_IRQP_SET ioctl");
430 exit(errno);
431 }
432
433 fprintf(stderr, "\n%ldHz:\t", tmp);
434 fflush(stderr);
435
436 /* Enable periodic interrupts */
437 retval = ioctl(fd, RTC_PIE_ON, 0);
438 if (retval == -1) {
439 perror("RTC_PIE_ON ioctl");
440 exit(errno);
441 }
442
443 for (i=1; i<21; i++) {
444 /* This blocks */
445 retval = read(fd, &data, sizeof(unsigned long));
446 if (retval == -1) {
447 perror("read");
448 exit(errno);
449 }
450 fprintf(stderr, " %d",i);
451 fflush(stderr);
452 irqcount++;
453 }
454
455 /* Disable periodic interrupts */
456 retval = ioctl(fd, RTC_PIE_OFF, 0);
457 if (retval == -1) {
458 perror("RTC_PIE_OFF ioctl");
459 exit(errno);
460 }
461 }
462
463done:
464 fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
465
466 close(fd);
467
468 return 0;
469}
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}