Commit 7531d8faa85f8880db433027bf2b04950e49baeb

Authored by David Brownell
Committed by Linus Torvalds
1 parent 4d8ebddcc5

[PATCH] Documentation/rtc.txt updates (for rtc class)

This updates the RTC documentation to summarize the two APIs now available:
the old PC/AT one, and the new RTC class drivers.  It also updates the
included "rtctest.c" file to better meet Linux style guidelines, and to work
with the new RTC drivers.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 1 changed file with 304 additions and 159 deletions Side-by-side Diff

Documentation/rtc.txt
1 1  
2   - Real Time Clock Driver for Linux
3   - ================================
  2 + Real Time Clock (RTC) Drivers for Linux
  3 + =======================================
4 4  
  5 +When Linux developers talk about a "Real Time Clock", they usually mean
  6 +something that tracks wall clock time and is battery backed so that it
  7 +works even with system power off. Such clocks will normally not track
  8 +the local time zone or daylight savings time -- unless they dual boot
  9 +with MS-Windows -- but will instead be set to Coordinated Universal Time
  10 +(UTC, formerly "Greenwich Mean Time").
  11 +
  12 +The newest non-PC hardware tends to just count seconds, like the time(2)
  13 +system call reports, but RTCs also very commonly represent time using
  14 +the Gregorian calendar and 24 hour time, as reported by gmtime(3).
  15 +
  16 +Linux has two largely-compatible userspace RTC API families you may
  17 +need to know about:
  18 +
  19 + * /dev/rtc ... is the RTC provided by PC compatible systems,
  20 + so it's not very portable to non-x86 systems.
  21 +
  22 + * /dev/rtc0, /dev/rtc1 ... are part of a framework that's
  23 + supported by a wide variety of RTC chips on all systems.
  24 +
  25 +Programmers need to understand that the PC/AT functionality is not
  26 +always available, and some systems can do much more. That is, the
  27 +RTCs use the same API to make requests in both RTC frameworks (using
  28 +different filenames of course), but the hardware may not offer the
  29 +same functionality. For example, not every RTC is hooked up to an
  30 +IRQ, so they can't all issue alarms; and where standard PC RTCs can
  31 +only issue an alarm up to 24 hours in the future, other hardware may
  32 +be able to schedule one any time in the upcoming century.
  33 +
  34 +
  35 + Old PC/AT-Compatible driver: /dev/rtc
  36 + --------------------------------------
  37 +
5 38 All PCs (even Alpha machines) have a Real Time Clock built into them.
6 39 Usually they are built into the chipset of the computer, but some may
7 40 actually have a Motorola MC146818 (or clone) on the board. This is the
8 41 clock that keeps the date and time while your computer is turned off.
9 42  
  43 +ACPI has standardized that MC146818 functionality, and extended it in
  44 +a few ways (enabling longer alarm periods, and wake-from-hibernate).
  45 +That functionality is NOT exposed in the old driver.
  46 +
10 47 However it can also be used to generate signals from a slow 2Hz to a
11 48 relatively fast 8192Hz, in increments of powers of two. These signals
12 49 are reported by interrupt number 8. (Oh! So *that* is what IRQ 8 is
13 50  
14 51  
15 52  
16 53  
17 54  
18 55  
19 56  
20 57  
21 58  
22 59  
23 60  
24 61  
25 62  
26 63  
27 64  
28 65  
29 66  
30 67  
31 68  
32 69  
33 70  
34 71  
35 72  
36 73  
37 74  
38 75  
39 76  
40 77  
41 78  
42 79  
43 80  
44 81  
45 82  
46 83  
47 84  
48 85  
49 86  
50 87  
51 88  
52 89  
53 90  
54 91  
... ... @@ -63,224 +100,332 @@
63 100 perhaps more useful to include a small test program that demonstrates
64 101 how to use them, and demonstrates the features of the driver. This is
65 102 probably a lot more useful to people interested in writing applications
66   -that will be using this driver.
  103 +that will be using this driver. See the code at the end of this document.
67 104  
68   - Paul Gortmaker
  105 +(The original /dev/rtc driver was written by Paul Gortmaker.)
69 106  
  107 +
  108 + New portable "RTC Class" drivers: /dev/rtcN
  109 + --------------------------------------------
  110 +
  111 +Because Linux supports many non-ACPI and non-PC platforms, some of which
  112 +have more than one RTC style clock, it needed a more portable solution
  113 +than expecting a single battery-backed MC146818 clone on every system.
  114 +Accordingly, a new "RTC Class" framework has been defined. It offers
  115 +three different userspace interfaces:
  116 +
  117 + * /dev/rtcN ... much the same as the older /dev/rtc interface
  118 +
  119 + * /sys/class/rtc/rtcN ... sysfs attributes support readonly
  120 + access to some RTC attributes.
  121 +
  122 + * /proc/driver/rtc ... the first RTC (rtc0) may expose itself
  123 + using a procfs interface. More information is (currently) shown
  124 + here than through sysfs.
  125 +
  126 +The RTC Class framework supports a wide variety of RTCs, ranging from those
  127 +integrated into embeddable system-on-chip (SOC) processors to discrete chips
  128 +using I2C, SPI, or some other bus to communicate with the host CPU. There's
  129 +even support for PC-style RTCs ... including the features exposed on newer PCs
  130 +through ACPI.
  131 +
  132 +The new framework also removes the "one RTC per system" restriction. For
  133 +example, maybe the low-power battery-backed RTC is a discrete I2C chip, but
  134 +a high functionality RTC is integrated into the SOC. That system might read
  135 +the system clock from the discrete RTC, but use the integrated one for all
  136 +other tasks, because of its greater functionality.
  137 +
  138 +The ioctl() calls supported by /dev/rtc are also supported by the RTC class
  139 +framework. However, because the chips and systems are not standardized,
  140 +some PC/AT functionality might not be provided. And in the same way, some
  141 +newer features -- including those enabled by ACPI -- are exposed by the
  142 +RTC class framework, but can't be supported by the older driver.
  143 +
  144 + * RTC_RD_TIME, RTC_SET_TIME ... every RTC supports at least reading
  145 + time, returning the result as a Gregorian calendar date and 24 hour
  146 + wall clock time. To be most useful, this time may also be updated.
  147 +
  148 + * RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC
  149 + is connected to an IRQ line, it can often issue an alarm IRQ up to
  150 + 24 hours in the future.
  151 +
  152 + * RTC_WKALM_SET, RTC_WKALM_READ ... RTCs that can issue alarms beyond
  153 + the next 24 hours use a slightly more powerful API, which supports
  154 + setting the longer alarm time and enabling its IRQ using a single
  155 + request (using the same model as EFI firmware).
  156 +
  157 + * RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, it probably
  158 + also offers update IRQs whenever the "seconds" counter changes.
  159 + If needed, the RTC framework can emulate this mechanism.
  160 +
  161 + * RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... another
  162 + feature often accessible with an IRQ line is a periodic IRQ, issued
  163 + at settable frequencies (usually 2^N Hz).
  164 +
  165 +In many cases, the RTC alarm can be a system wake event, used to force
  166 +Linux out of a low power sleep state (or hibernation) back to a fully
  167 +operational state. For example, a system could enter a deep power saving
  168 +state until it's time to execute some scheduled tasks.
  169 +
  170 +
70 171 -------------------- 8< ---------------- 8< -----------------------------
71 172  
72 173 /*
73   - * Real Time Clock Driver Test/Example Program
  174 + * Real Time Clock Driver Test/Example Program
74 175 *
75   - * Compile with:
76   - * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
  176 + * Compile with:
  177 + * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
77 178 *
78   - * Copyright (C) 1996, Paul Gortmaker.
  179 + * Copyright (C) 1996, Paul Gortmaker.
79 180 *
80   - * Released under the GNU General Public License, version 2,
81   - * included herein by reference.
  181 + * Released under the GNU General Public License, version 2,
  182 + * included herein by reference.
82 183 *
83 184 */
84 185  
85 186 #include <stdio.h>
86   -#include <stdlib.h>
87 187 #include <linux/rtc.h>
88 188 #include <sys/ioctl.h>
89 189 #include <sys/time.h>
90 190 #include <sys/types.h>
91 191 #include <fcntl.h>
92 192 #include <unistd.h>
  193 +#include <stdlib.h>
93 194 #include <errno.h>
94 195  
95   -int main(void) {
96 196  
97   -int i, fd, retval, irqcount = 0;
98   -unsigned long tmp, data;
99   -struct rtc_time rtc_tm;
  197 +/*
  198 + * This expects the new RTC class driver framework, working with
  199 + * clocks that will often not be clones of what the PC-AT had.
  200 + * Use the command line to specify another RTC if you need one.
  201 + */
  202 +static const char default_rtc[] = "/dev/rtc0";
100 203  
101   -fd = open ("/dev/rtc", O_RDONLY);
102 204  
103   -if (fd == -1) {
104   - perror("/dev/rtc");
105   - exit(errno);
106   -}
  205 +int main(int argc, char **argv)
  206 +{
  207 + int i, fd, retval, irqcount = 0;
  208 + unsigned long tmp, data;
  209 + struct rtc_time rtc_tm;
  210 + const char *rtc = default_rtc;
107 211  
108   -fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");
  212 + switch (argc) {
  213 + case 2:
  214 + rtc = argv[1];
  215 + /* FALLTHROUGH */
  216 + case 1:
  217 + break;
  218 + default:
  219 + fprintf(stderr, "usage: rtctest [rtcdev]\n");
  220 + return 1;
  221 + }
109 222  
110   -/* Turn on update interrupts (one per second) */
111   -retval = ioctl(fd, RTC_UIE_ON, 0);
112   -if (retval == -1) {
113   - perror("ioctl");
114   - exit(errno);
115   -}
  223 + fd = open(rtc, O_RDONLY);
116 224  
117   -fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading /dev/rtc:");
118   -fflush(stderr);
119   -for (i=1; i<6; i++) {
120   - /* This read will block */
121   - retval = read(fd, &data, sizeof(unsigned long));
  225 + if (fd == -1) {
  226 + perror(rtc);
  227 + exit(errno);
  228 + }
  229 +
  230 + fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");
  231 +
  232 + /* Turn on update interrupts (one per second) */
  233 + retval = ioctl(fd, RTC_UIE_ON, 0);
122 234 if (retval == -1) {
123   - perror("read");
  235 + if (errno == ENOTTY) {
  236 + fprintf(stderr,
  237 + "\n...Update IRQs not supported.\n");
  238 + goto test_READ;
  239 + }
  240 + perror("ioctl");
124 241 exit(errno);
125 242 }
126   - fprintf(stderr, " %d",i);
  243 +
  244 + fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:",
  245 + rtc);
127 246 fflush(stderr);
128   - irqcount++;
129   -}
  247 + for (i=1; i<6; i++) {
  248 + /* This read will block */
  249 + retval = read(fd, &data, sizeof(unsigned long));
  250 + if (retval == -1) {
  251 + perror("read");
  252 + exit(errno);
  253 + }
  254 + fprintf(stderr, " %d",i);
  255 + fflush(stderr);
  256 + irqcount++;
  257 + }
130 258  
131   -fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
132   -fflush(stderr);
133   -for (i=1; i<6; i++) {
134   - struct timeval tv = {5, 0}; /* 5 second timeout on select */
135   - fd_set readfds;
  259 + fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
  260 + fflush(stderr);
  261 + for (i=1; i<6; i++) {
  262 + struct timeval tv = {5, 0}; /* 5 second timeout on select */
  263 + fd_set readfds;
136 264  
137   - FD_ZERO(&readfds);
138   - FD_SET(fd, &readfds);
139   - /* The select will wait until an RTC interrupt happens. */
140   - retval = select(fd+1, &readfds, NULL, NULL, &tv);
  265 + FD_ZERO(&readfds);
  266 + FD_SET(fd, &readfds);
  267 + /* The select will wait until an RTC interrupt happens. */
  268 + retval = select(fd+1, &readfds, NULL, NULL, &tv);
  269 + if (retval == -1) {
  270 + perror("select");
  271 + exit(errno);
  272 + }
  273 + /* This read won't block unlike the select-less case above. */
  274 + retval = read(fd, &data, sizeof(unsigned long));
  275 + if (retval == -1) {
  276 + perror("read");
  277 + exit(errno);
  278 + }
  279 + fprintf(stderr, " %d",i);
  280 + fflush(stderr);
  281 + irqcount++;
  282 + }
  283 +
  284 + /* Turn off update interrupts */
  285 + retval = ioctl(fd, RTC_UIE_OFF, 0);
141 286 if (retval == -1) {
142   - perror("select");
  287 + perror("ioctl");
143 288 exit(errno);
144 289 }
145   - /* This read won't block unlike the select-less case above. */
146   - retval = read(fd, &data, sizeof(unsigned long));
  290 +
  291 +test_READ:
  292 + /* Read the RTC time/date */
  293 + retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
147 294 if (retval == -1) {
148   - perror("read");
  295 + perror("ioctl");
149 296 exit(errno);
150 297 }
151   - fprintf(stderr, " %d",i);
152   - fflush(stderr);
153   - irqcount++;
154   -}
155 298  
156   -/* Turn off update interrupts */
157   -retval = ioctl(fd, RTC_UIE_OFF, 0);
158   -if (retval == -1) {
159   - perror("ioctl");
160   - exit(errno);
161   -}
  299 + fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
  300 + rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
  301 + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
162 302  
163   -/* Read the RTC time/date */
164   -retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
165   -if (retval == -1) {
166   - perror("ioctl");
167   - exit(errno);
168   -}
  303 + /* Set the alarm to 5 sec in the future, and check for rollover */
  304 + rtc_tm.tm_sec += 5;
  305 + if (rtc_tm.tm_sec >= 60) {
  306 + rtc_tm.tm_sec %= 60;
  307 + rtc_tm.tm_min++;
  308 + }
  309 + if (rtc_tm.tm_min == 60) {
  310 + rtc_tm.tm_min = 0;
  311 + rtc_tm.tm_hour++;
  312 + }
  313 + if (rtc_tm.tm_hour == 24)
  314 + rtc_tm.tm_hour = 0;
169 315  
170   -fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
171   - rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
172   - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
  316 + retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
  317 + if (retval == -1) {
  318 + if (errno == ENOTTY) {
  319 + fprintf(stderr,
  320 + "\n...Alarm IRQs not supported.\n");
  321 + goto test_PIE;
  322 + }
  323 + perror("ioctl");
  324 + exit(errno);
  325 + }
173 326  
174   -/* Set the alarm to 5 sec in the future, and check for rollover */
175   -rtc_tm.tm_sec += 5;
176   -if (rtc_tm.tm_sec >= 60) {
177   - rtc_tm.tm_sec %= 60;
178   - rtc_tm.tm_min++;
179   -}
180   -if (rtc_tm.tm_min == 60) {
181   - rtc_tm.tm_min = 0;
182   - rtc_tm.tm_hour++;
183   -}
184   -if (rtc_tm.tm_hour == 24)
185   - rtc_tm.tm_hour = 0;
  327 + /* Read the current alarm settings */
  328 + retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
  329 + if (retval == -1) {
  330 + perror("ioctl");
  331 + exit(errno);
  332 + }
186 333  
187   -retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
188   -if (retval == -1) {
189   - perror("ioctl");
190   - exit(errno);
191   -}
  334 + fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
  335 + rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
192 336  
193   -/* Read the current alarm settings */
194   -retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
195   -if (retval == -1) {
196   - perror("ioctl");
197   - exit(errno);
198   -}
199   -
200   -fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
201   - rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
202   -
203   -/* Enable alarm interrupts */
204   -retval = ioctl(fd, RTC_AIE_ON, 0);
205   -if (retval == -1) {
206   - perror("ioctl");
207   - exit(errno);
208   -}
209   -
210   -fprintf(stderr, "Waiting 5 seconds for alarm...");
211   -fflush(stderr);
212   -/* This blocks until the alarm ring causes an interrupt */
213   -retval = read(fd, &data, sizeof(unsigned long));
214   -if (retval == -1) {
215   - perror("read");
216   - exit(errno);
217   -}
218   -irqcount++;
219   -fprintf(stderr, " okay. Alarm rang.\n");
220   -
221   -/* Disable alarm interrupts */
222   -retval = ioctl(fd, RTC_AIE_OFF, 0);
223   -if (retval == -1) {
224   - perror("ioctl");
225   - exit(errno);
226   -}
227   -
228   -/* Read periodic IRQ rate */
229   -retval = ioctl(fd, RTC_IRQP_READ, &tmp);
230   -if (retval == -1) {
231   - perror("ioctl");
232   - exit(errno);
233   -}
234   -fprintf(stderr, "\nPeriodic IRQ rate was %ldHz.\n", tmp);
235   -
236   -fprintf(stderr, "Counting 20 interrupts at:");
237   -fflush(stderr);
238   -
239   -/* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
240   -for (tmp=2; tmp<=64; tmp*=2) {
241   -
242   - retval = ioctl(fd, RTC_IRQP_SET, tmp);
  337 + /* Enable alarm interrupts */
  338 + retval = ioctl(fd, RTC_AIE_ON, 0);
243 339 if (retval == -1) {
244 340 perror("ioctl");
245 341 exit(errno);
246 342 }
247 343  
248   - fprintf(stderr, "\n%ldHz:\t", tmp);
  344 + fprintf(stderr, "Waiting 5 seconds for alarm...");
249 345 fflush(stderr);
  346 + /* This blocks until the alarm ring causes an interrupt */
  347 + retval = read(fd, &data, sizeof(unsigned long));
  348 + if (retval == -1) {
  349 + perror("read");
  350 + exit(errno);
  351 + }
  352 + irqcount++;
  353 + fprintf(stderr, " okay. Alarm rang.\n");
250 354  
251   - /* Enable periodic interrupts */
252   - retval = ioctl(fd, RTC_PIE_ON, 0);
  355 + /* Disable alarm interrupts */
  356 + retval = ioctl(fd, RTC_AIE_OFF, 0);
253 357 if (retval == -1) {
254 358 perror("ioctl");
255 359 exit(errno);
256 360 }
257 361  
258   - for (i=1; i<21; i++) {
259   - /* This blocks */
260   - retval = read(fd, &data, sizeof(unsigned long));
  362 +test_PIE:
  363 + /* Read periodic IRQ rate */
  364 + retval = ioctl(fd, RTC_IRQP_READ, &tmp);
  365 + if (retval == -1) {
  366 + /* not all RTCs support periodic IRQs */
  367 + if (errno == ENOTTY) {
  368 + fprintf(stderr, "\nNo periodic IRQ support\n");
  369 + return 0;
  370 + }
  371 + perror("ioctl");
  372 + exit(errno);
  373 + }
  374 + fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp);
  375 +
  376 + fprintf(stderr, "Counting 20 interrupts at:");
  377 + fflush(stderr);
  378 +
  379 + /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
  380 + for (tmp=2; tmp<=64; tmp*=2) {
  381 +
  382 + retval = ioctl(fd, RTC_IRQP_SET, tmp);
261 383 if (retval == -1) {
262   - perror("read");
263   - exit(errno);
  384 + /* not all RTCs can change their periodic IRQ rate */
  385 + if (errno == ENOTTY) {
  386 + fprintf(stderr,
  387 + "\n...Periodic IRQ rate is fixed\n");
  388 + goto done;
  389 + }
  390 + perror("ioctl");
  391 + exit(errno);
264 392 }
265   - fprintf(stderr, " %d",i);
  393 +
  394 + fprintf(stderr, "\n%ldHz:\t", tmp);
266 395 fflush(stderr);
267   - irqcount++;
268   - }
269 396  
270   - /* Disable periodic interrupts */
271   - retval = ioctl(fd, RTC_PIE_OFF, 0);
272   - if (retval == -1) {
273   - perror("ioctl");
274   - exit(errno);
  397 + /* Enable periodic interrupts */
  398 + retval = ioctl(fd, RTC_PIE_ON, 0);
  399 + if (retval == -1) {
  400 + perror("ioctl");
  401 + exit(errno);
  402 + }
  403 +
  404 + for (i=1; i<21; i++) {
  405 + /* This blocks */
  406 + retval = read(fd, &data, sizeof(unsigned long));
  407 + if (retval == -1) {
  408 + perror("read");
  409 + exit(errno);
  410 + }
  411 + fprintf(stderr, " %d",i);
  412 + fflush(stderr);
  413 + irqcount++;
  414 + }
  415 +
  416 + /* Disable periodic interrupts */
  417 + retval = ioctl(fd, RTC_PIE_OFF, 0);
  418 + if (retval == -1) {
  419 + perror("ioctl");
  420 + exit(errno);
  421 + }
275 422 }
276   -}
277 423  
278   -fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
279   -fprintf(stderr, "\nTyping \"cat /proc/interrupts\" will show %d more events on IRQ 8.\n\n",
280   - irqcount);
  424 +done:
  425 + fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
281 426  
282   -close(fd);
283   -return 0;
  427 + close(fd);
284 428  
285   -} /* end main */
  429 + return 0;
  430 +}