[kernel] update to 2.6.25.12
[openwrt.git] / target / linux / generic-2.6 / patches-2.6.23 / 230-pps_support.patch
1 --- /dev/null
2 +++ b/Documentation/pps/Makefile
3 @@ -0,0 +1,27 @@
4 +TARGETS = ppstest ppsctl
5 +
6 +CFLAGS += -Wall -O2 -D_GNU_SOURCE
7 +CFLAGS += -I .
8 +CFLAGS += -ggdb
9 +
10 +# -- Actions section ----------------------------------------------------------
11 +
12 +.PHONY : all depend dep
13 +
14 +all : .depend $(TARGETS)
15 +
16 +.depend depend dep :
17 +       $(CC) $(CFLAGS) -M $(TARGETS:=.c) > .depend
18 +
19 +ifeq (.depend,$(wildcard .depend))
20 +include .depend
21 +endif
22 +
23 +
24 +# -- Clean section ------------------------------------------------------------
25 +
26 +.PHONY : clean
27 +
28 +clean :
29 +       rm -f *.o *~ core .depend
30 +       rm -f ${TARGETS}
31 --- /dev/null
32 +++ b/Documentation/pps/pps.txt
33 @@ -0,0 +1,170 @@
34 +
35 +                       PPS - Pulse Per Second
36 +                       ----------------------
37 +
38 +(C) Copyright 2007 Rodolfo Giometti <giometti@enneenne.com>
39 +
40 +This program is free software; you can redistribute it and/or modify
41 +it under the terms of the GNU General Public License as published by
42 +the Free Software Foundation; either version 2 of the License, or
43 +(at your option) any later version.
44 +
45 +This program is distributed in the hope that it will be useful,
46 +but WITHOUT ANY WARRANTY; without even the implied warranty of
47 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48 +GNU General Public License for more details.
49 +
50 +
51 +
52 +Overview
53 +--------
54 +
55 +LinuxPPS provides a programming interface (API) to define into the
56 +system several PPS sources.
57 +
58 +PPS means "pulse per second" and a PPS source is just a device which
59 +provides a high precision signal each second so that an application
60 +can use it to adjust system clock time.
61 +
62 +A PPS source can be connected to a serial port (usually to the Data
63 +Carrier Detect pin) or to a parallel port (ACK-pin) or to a special
64 +CPU's GPIOs (this is the common case in embedded systems) but in each
65 +case when a new pulse comes the system must apply to it a timestamp
66 +and record it for the userland.
67 +
68 +Common use is the combination of the NTPD as userland program with a
69 +GPS receiver as PPS source to obtain a wallclock-time with
70 +sub-millisecond synchronisation to UTC.
71 +
72 +
73 +RFC considerations
74 +------------------
75 +
76 +While implementing a PPS API as RFC 2783 defines and using an embedded
77 +CPU GPIO-Pin as physical link to the signal, I encountered a deeper
78 +problem:
79 +
80 +   At startup it needs a file descriptor as argument for the function
81 +   time_pps_create().
82 +
83 +This implies that the source has a /dev/... entry. This assumption is
84 +ok for the serial and parallel port, where you can do something
85 +useful besides(!) the gathering of timestamps as it is the central
86 +task for a PPS-API. But this assumption does not work for a single
87 +purpose GPIO line. In this case even basic file-related functionality
88 +(like read() and write()) makes no sense at all and should not be a
89 +precondition for the use of a PPS-API.
90 +
91 +The problem can be simply solved if you consider that a PPS source is
92 +not always connected with a GPS data source.
93 +
94 +So your programs should check if the GPS data source (the serial port
95 +for instance) is a PPS source too, otherwise they should provide the
96 +possibility to open another device as PPS source.
97 +
98 +In LinuxPPS the PPS sources are simply char devices usually mapped
99 +into files /dev/pps0, /dev/pps1, etc..
100 +
101 +
102 +Coding example
103 +--------------
104 +
105 +To register a PPS source into the kernel you should define a struct
106 +pps_source_info_s as follow:
107 +
108 +    static struct pps_source_info_s pps_ktimer_info = {
109 +            name         : "ktimer",
110 +            path         : "",
111 +            mode         : PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \
112 +                          PPS_ECHOASSERT | \
113 +                           PPS_CANWAIT | PPS_TSFMT_TSPEC,
114 +            echo         : pps_ktimer_echo,
115 +            owner        : THIS_MODULE,
116 +    };
117 +
118 +and then calling the function pps_register_source() in your
119 +intialization routine as follow:
120 +
121 +    source = pps_register_source(&pps_ktimer_info,
122 +                       PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
123 +
124 +The pps_register_source() prototype is:
125 +
126 +  int pps_register_source(struct pps_source_info_s *info, int default_params)
127 +
128 +where "info" is a pointer to a structure that describes a particular
129 +PPS source, "default_params" tells the system what the initial default
130 +parameters for the device should be (is obvious that these parameters
131 +must be a subset of ones defined into the struct
132 +pps_source_info_s which describe the capabilities of the driver).
133 +
134 +Once you have registered a new PPS source into the system you can
135 +signal an assert event (for example in the interrupt handler routine)
136 +just using:
137 +
138 +    pps_event(source, PPS_CAPTUREASSERT, ptr);
139 +
140 +The same function may also run the defined echo function
141 +(pps_ktimer_echo(), passing to it the "ptr" pointer) if the user
142 +asked for that... etc..
143 +
144 +Please see the file drivers/pps/clients/ktimer.c for an example code.
145 +
146 +
147 +SYSFS support
148 +-------------
149 +
150 +If the SYSFS filesystem is enabled in the kernel it provides a new class:
151 +
152 +   $ ls /sys/class/pps/
153 +   pps0/  pps1/  pps2/
154 +
155 +Every directory is the ID of a PPS sources defined into the system and
156 +inside you find several files:
157 +
158 +    $ ls /sys/class/pps/pps0/
159 +    assert     clear  echo  mode  name  path  subsystem@  uevent
160 +
161 +Inside each "assert" and "clear" file you can find the timestamp and a
162 +sequence number:
163 +
164 +    $ cat /sys/class/pps/pps0/assert
165 +    1170026870.983207967#8
166 +
167 +Where before the "#" is the timestamp in seconds and after it is the
168 +sequence number. Other files are:
169 +
170 +* echo: reports if the PPS source has an echo function or not;
171 +
172 +* mode: reports available PPS functioning modes;
173 +
174 +* name: reports the PPS source's name;
175 +
176 +* path: reports the PPS source's device path, that is the device the
177 +  PPS source is connected to (if it exists).
178 +
179 +
180 +Testing the PPS support
181 +-----------------------
182 +
183 +In order to test the PPS support even without specific hardware you can use
184 +the ktimer driver (see the client subsection in the PPS configuration menu)
185 +and the userland tools provided into Documentaion/pps/ directory.
186 +
187 +Once you have enabled the compilation of ktimer just modprobe it (if
188 +not statically compiled):
189 +
190 +   # modprobe ktimer
191 +
192 +and the run ppstest as follow:
193 +
194 +   $ ./ppstest /dev/pps0
195 +   trying PPS source "/dev/pps1"
196 +   found PPS source "/dev/pps1"
197 +   ok, found 1 source(s), now start fetching data...
198 +   source 0 - assert 1186592699.388832443, sequence: 364 - clear  0.000000000, sequence: 0
199 +   source 0 - assert 1186592700.388931295, sequence: 365 - clear  0.000000000, sequence: 0
200 +   source 0 - assert 1186592701.389032765, sequence: 366 - clear  0.000000000, sequence: 0
201 +
202 +Please, note that to compile userland programs you need the file timepps.h
203 +(see Documentation/pps/).
204 --- /dev/null
205 +++ b/Documentation/pps/ppsctl.c
206 @@ -0,0 +1,62 @@
207 +#include <stdio.h>
208 +#include <unistd.h>
209 +#include <stdlib.h>
210 +#include <errno.h>
211 +#include <sys/ioctl.h>
212 +#include <sys/types.h>
213 +#include <sys/stat.h>
214 +#include <fcntl.h>
215 +#include <string.h>
216 +#include <linux/serial.h>
217 +
218 +void usage(char *name)
219 +{
220 +       fprintf(stderr, "usage: %s <ttyS> [enable|disable]\n", name);
221 +
222 +       exit(EXIT_FAILURE);
223 +}
224 +
225 +int main(int argc, char *argv[])
226 +{
227 +       int fd;
228 +       int ret;
229 +       struct serial_struct ss;
230 +
231 +       if (argc < 2)
232 +               usage(argv[0]);
233 +
234 +       fd = open(argv[1], O_RDWR);
235 +       if (fd < 0) {
236 +               perror("open");
237 +               exit(EXIT_FAILURE);
238 +       }
239 +
240 +       ret = ioctl(fd, TIOCGSERIAL, &ss);
241 +       if (ret < 0) {
242 +               perror("ioctl(TIOCGSERIAL)");
243 +               exit(EXIT_FAILURE);
244 +       }
245 +
246 +       if (argc < 3) {         /* just read PPS status */
247 +               printf("PPS is %sabled\n",
248 +                      ss.flags & ASYNC_HARDPPS_CD ? "en" : "dis");
249 +               exit(EXIT_SUCCESS);
250 +       }
251 +
252 +       if (argv[2][0] == 'e' || argv[2][0] == '1')
253 +               ss.flags |= ASYNC_HARDPPS_CD;
254 +       else if (argv[2][0] == 'd' || argv[2][0] == '0')
255 +               ss.flags &= ~ASYNC_HARDPPS_CD;
256 +       else {
257 +               fprintf(stderr, "invalid state argument \"%s\"\n", argv[2]);
258 +               exit(EXIT_FAILURE);
259 +       }
260 +
261 +       ret = ioctl(fd, TIOCSSERIAL, &ss);
262 +       if (ret < 0) {
263 +               perror("ioctl(TIOCSSERIAL)");
264 +               exit(EXIT_FAILURE);
265 +       }
266 +
267 +       return 0;
268 +}
269 --- /dev/null
270 +++ b/Documentation/pps/ppsfind
271 @@ -0,0 +1,17 @@
272 +#!/bin/sh
273 +
274 +SYS="/sys/class/pps/"
275 +
276 +if [ $# -lt 1 ] ; then
277 +       echo "usage: ppsfind <name>" >&2
278 +       exit 1
279 +fi
280 +
281 +for d in $(ls $SYS) ; do
282 +       if grep $1 $SYS/$d/name >& /dev/null || \
283 +          grep $1 $SYS/$d/path >& /dev/null ; then
284 +               echo "$d: name=$(cat $SYS/$d/name) path=$(cat $SYS/$d/path)"
285 +       fi
286 +done
287 +
288 +exit 0
289 --- /dev/null
290 +++ b/Documentation/pps/ppstest.c
291 @@ -0,0 +1,151 @@
292 +#include <stdio.h>
293 +#include <stdlib.h>
294 +#include <unistd.h>
295 +#include <errno.h>
296 +#include <string.h>
297 +#include <sys/types.h>
298 +#include <sys/stat.h>
299 +#include <fcntl.h>
300 +
301 +#include <timepps.h>
302 +
303 +int find_source(char *path, pps_handle_t *handle, int *avail_mode)
304 +{
305 +       pps_params_t params;
306 +       int ret;
307 +
308 +       printf("trying PPS source \"%s\"\n", path);
309 +
310 +       /* Try to find the source by using the supplied "path" name */
311 +       ret = open(path, O_RDWR);
312 +       if (ret < 0) {
313 +               fprintf(stderr, "unable to open device \"%s\" (%m)\n", path);
314 +               return ret;
315 +       }
316 +
317 +       /* Open the PPS source (and check the file descriptor) */
318 +       ret = time_pps_create(ret, handle);
319 +       if (ret < 0) {
320 +               fprintf(stderr, "cannot create a PPS source from device "
321 +                               "\"%s\" (%m)\n", path);
322 +               return -1;
323 +       }
324 +       printf("found PPS source \"%s\"\n", path);
325 +
326 +       /* Find out what features are supported */
327 +       ret = time_pps_getcap(*handle, avail_mode);
328 +       if (ret < 0) {
329 +               fprintf(stderr, "cannot get capabilities (%m)\n");
330 +               return -1;
331 +       }
332 +       if ((*avail_mode & PPS_CAPTUREASSERT) == 0) {
333 +               fprintf(stderr, "cannot CAPTUREASSERT\n");
334 +               return -1;
335 +       }
336 +       if ((*avail_mode & PPS_OFFSETASSERT) == 0) {
337 +               fprintf(stderr, "cannot OFFSETASSERT\n");
338 +               return -1;
339 +       }
340 +
341 +       /* Capture assert timestamps, and compensate for a 675 nsec
342 +        * propagation delay */
343 +       ret = time_pps_getparams(*handle, &params);
344 +       if (ret < 0) {
345 +               fprintf(stderr, "cannot get parameters (%m)\n");
346 +               return -1;
347 +       }
348 +       params.assert_offset.tv_sec = 0;
349 +       params.assert_offset.tv_nsec = 675;
350 +       params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
351 +       ret = time_pps_setparams(*handle, &params);
352 +       if (ret < 0) {
353 +               fprintf(stderr, "cannot set parameters (%m)\n");
354 +               return -1;
355 +       }
356 +
357 +       return 0;
358 +}
359 +
360 +int fetch_source(int i, pps_handle_t *handle, int *avail_mode)
361 +{
362 +       struct timespec timeout;
363 +       pps_info_t infobuf;
364 +       int ret;
365 +
366 +       /* create a zero-valued timeout */
367 +       timeout.tv_sec = 3;
368 +       timeout.tv_nsec = 0;
369 +
370 +retry:
371 +       if (*avail_mode & PPS_CANWAIT) /* waits for the next event */
372 +               ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,
373 +                                  &timeout);
374 +       else {
375 +               sleep(1);
376 +               ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,
377 +                                  &timeout);
378 +       }
379 +       if (ret < 0) {
380 +               if (ret == -EINTR) {
381 +                       fprintf(stderr, "time_pps_fetch() got a signal!\n");
382 +                       goto retry;
383 +               }
384 +
385 +               fprintf(stderr, "time_pps_fetch() error %d (%m)\n", ret);
386 +               return -1;
387 +       }
388 +
389 +       printf("source %d - "
390 +              "assert %ld.%09ld, sequence: %ld - "
391 +              "clear  %ld.%09ld, sequence: %ld\n",
392 +              i,
393 +              infobuf.assert_timestamp.tv_sec,
394 +              infobuf.assert_timestamp.tv_nsec,
395 +              infobuf.assert_sequence,
396 +              infobuf.clear_timestamp.tv_sec,
397 +              infobuf.clear_timestamp.tv_nsec, infobuf.clear_sequence);
398 +
399 +       return 0;
400 +}
401 +
402 +void usage(char *name)
403 +{
404 +       fprintf(stderr, "usage: %s <ppsdev> [<ppsdev> ...]\n", name);
405 +       exit(EXIT_FAILURE);
406 +}
407 +
408 +int main(int argc, char *argv[])
409 +{
410 +       int num;
411 +       pps_handle_t handle[4];
412 +       int avail_mode[4];
413 +       int i = 0;
414 +       int ret;
415 +
416 +       /* Check the command line */
417 +       if (argc < 2)
418 +               usage(argv[0]);
419 +
420 +       for (i = 1; i < argc && i <= 4; i++) {
421 +               ret = find_source(argv[i], &handle[i - 1], &avail_mode[i - 1]);
422 +               if (ret < 0)
423 +                       exit(EXIT_FAILURE);
424 +       }
425 +
426 +       num = i - 1;
427 +       printf("ok, found %d source(s), now start fetching data...\n", num);
428 +
429 +       /* loop, printing the most recent timestamp every second or so */
430 +       while (1) {
431 +               for (i = 0; i < num; i++) {
432 +                       ret = fetch_source(i, &handle[i], &avail_mode[i]);
433 +                       if (ret < 0 && errno != ETIMEDOUT)
434 +                               exit(EXIT_FAILURE);
435 +               }
436 +       }
437 +
438 +       for (; i >= 0; i--)
439 +               time_pps_destroy(handle[i]);
440 +
441 +       return 0;
442 +}
443 --- /dev/null
444 +++ b/Documentation/pps/timepps.h
445 @@ -0,0 +1,193 @@
446 +/*
447 + * timepps.h -- PPS API main header
448 + *
449 + * Copyright (C) 2005-2007   Rodolfo Giometti <giometti@linux.it>
450 + *
451 + *   This program is free software; you can redistribute it and/or modify
452 + *   it under the terms of the GNU General Public License as published by
453 + *   the Free Software Foundation; either version 2 of the License, or
454 + *   (at your option) any later version.
455 + *
456 + *   This program is distributed in the hope that it will be useful,
457 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
458 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
459 + *   GNU General Public License for more details.
460 + *
461 + *   You should have received a copy of the GNU General Public License
462 + *   along with this program; if not, write to the Free Software
463 + *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
464 + */
465 +
466 +#ifndef _SYS_TIMEPPS_H_
467 +#define _SYS_TIMEPPS_H_
468 +
469 +#include <sys/syscall.h>
470 +#include <unistd.h>
471 +#include <errno.h>
472 +#include <linux/pps.h>
473 +
474 +/*
475 + * New data structures
476 + */
477 +
478 +struct ntp_fp {
479 +       unsigned int integral;
480 +       unsigned int fractional;
481 +};
482 +
483 +union pps_timeu {
484 +       struct timespec tspec;
485 +       struct ntp_fp ntpfp;
486 +       unsigned long longpad[3];
487 +};
488 +
489 +struct pps_info {
490 +       unsigned long assert_sequence;  /* seq. num. of assert event */
491 +       unsigned long clear_sequence;   /* seq. num. of clear event */
492 +       union pps_timeu assert_tu;      /* time of assert event */
493 +       union pps_timeu clear_tu;       /* time of clear event */
494 +       int current_mode;               /* current mode bits */
495 +};
496 +
497 +struct pps_params {
498 +       int api_version;                /* API version # */
499 +       int mode;                       /* mode bits */
500 +       union pps_timeu assert_off_tu;  /* offset compensation for assert */
501 +       union pps_timeu clear_off_tu;   /* offset compensation for clear */
502 +};
503 +
504 +typedef int pps_handle_t;              /* represents a PPS source */
505 +typedef unsigned long pps_seq_t;       /* sequence number */
506 +typedef struct ntp_fp ntp_fp_t;                /* NTP-compatible time stamp */
507 +typedef union pps_timeu pps_timeu_t;   /* generic data type for time stamps */
508 +typedef struct pps_info pps_info_t;
509 +typedef struct pps_params pps_params_t;
510 +
511 +#define assert_timestamp        assert_tu.tspec
512 +#define clear_timestamp         clear_tu.tspec
513 +
514 +#define assert_timestamp_ntpfp  assert_tu.ntpfp
515 +#define clear_timestamp_ntpfp   clear_tu.ntpfp
516 +
517 +#define assert_offset          assert_off_tu.tspec
518 +#define clear_offset           clear_off_tu.tspec
519 +
520 +#define assert_offset_ntpfp     assert_off_tu.ntpfp
521 +#define clear_offset_ntpfp      clear_off_tu.ntpfp
522 +
523 +/*
524 + * The PPS API
525 + */
526 +
527 +static __inline int time_pps_create(int source, pps_handle_t *handle)
528 +{
529 +       int ret;
530 +
531 +       if (!handle) {
532 +               errno = EINVAL;
533 +               return -1;
534 +       }
535 +
536 +       /* First we check if current device is a PPS valid PPS one...
537 +        */
538 +       ret = ioctl(source, PPS_CHECK);
539 +       if (ret) {
540 +               errno = EOPNOTSUPP;
541 +               return -1;
542 +       }
543 +
544 +       /* ... then since in LinuxPPS there are no differences between a
545 +        * "PPS source" and a "PPS handle", we simply return the same value.
546 +        */
547 +       *handle = source;
548 +
549 +       return 0;
550 +}
551 +
552 +static __inline int time_pps_destroy(pps_handle_t handle)
553 +{
554 +       return close(handle);
555 +}
556 +
557 +static __inline int time_pps_getparams(pps_handle_t handle,
558 +                                       pps_params_t *ppsparams)
559 +{
560 +       int ret;
561 +       struct pps_kparams __ppsparams;
562 +
563 +       ret = ioctl(handle, PPS_GETPARAMS, &__ppsparams);
564 +
565 +       ppsparams->api_version = __ppsparams.api_version;
566 +       ppsparams->mode = __ppsparams.mode;
567 +       ppsparams->assert_off_tu.tspec.tv_sec = __ppsparams.assert_off_tu.sec;
568 +       ppsparams->assert_off_tu.tspec.tv_nsec = __ppsparams.assert_off_tu.nsec;
569 +       ppsparams->clear_off_tu.tspec.tv_sec = __ppsparams.clear_off_tu.sec;
570 +       ppsparams->clear_off_tu.tspec.tv_nsec = __ppsparams.clear_off_tu.nsec;
571 +
572 +       return ret;
573 +}
574 +
575 +static __inline int time_pps_setparams(pps_handle_t handle,
576 +                                       const pps_params_t *ppsparams)
577 +{
578 +       struct pps_kparams __ppsparams;
579 +
580 +       __ppsparams.api_version = ppsparams->api_version;
581 +       __ppsparams.mode = ppsparams->mode;
582 +       __ppsparams.assert_off_tu.sec = ppsparams->assert_off_tu.tspec.tv_sec;
583 +       __ppsparams.assert_off_tu.nsec = ppsparams->assert_off_tu.tspec.tv_nsec;
584 +       __ppsparams.clear_off_tu.sec = ppsparams->clear_off_tu.tspec.tv_sec;
585 +       __ppsparams.clear_off_tu.nsec = ppsparams->clear_off_tu.tspec.tv_nsec;
586 +
587 +       return ioctl(handle, PPS_SETPARAMS, &__ppsparams);
588 +}
589 +
590 +/* Get capabilities for handle */
591 +static __inline int time_pps_getcap(pps_handle_t handle, int *mode)
592 +{
593 +       return ioctl(handle, PPS_GETCAP, mode);
594 +}
595 +
596 +static __inline int time_pps_fetch(pps_handle_t handle, const int tsformat,
597 +                                       pps_info_t *ppsinfobuf,
598 +                                       const struct timespec *timeout)
599 +{
600 +       struct pps_fdata __fdata;
601 +       int ret;
602 +
603 +       /* Sanity checks */
604 +       if (tsformat != PPS_TSFMT_TSPEC) {
605 +               errno = EINVAL;
606 +               return -1;
607 +       }
608 +
609 +       if (timeout) {
610 +               __fdata.timeout.sec = timeout->tv_sec;
611 +               __fdata.timeout.nsec = timeout->tv_nsec;
612 +               __fdata.timeout.flags = ~PPS_TIME_INVALID;
613 +       } else
614 +               __fdata.timeout.flags = PPS_TIME_INVALID;
615 +
616 +       ret = ioctl(handle, PPS_FETCH, &__fdata);
617 +
618 +       ppsinfobuf->assert_sequence = __fdata.info.assert_sequence;
619 +       ppsinfobuf->clear_sequence = __fdata.info.clear_sequence;
620 +       ppsinfobuf->assert_tu.tspec.tv_sec = __fdata.info.assert_tu.sec;
621 +       ppsinfobuf->assert_tu.tspec.tv_nsec = __fdata.info.assert_tu.nsec;
622 +       ppsinfobuf->clear_tu.tspec.tv_sec = __fdata.info.clear_tu.sec;
623 +       ppsinfobuf->clear_tu.tspec.tv_nsec = __fdata.info.clear_tu.nsec;
624 +       ppsinfobuf->current_mode = __fdata.info.current_mode;
625 +
626 +       return ret;
627 +}
628 +
629 +static __inline int time_pps_kcbind(pps_handle_t handle,
630 +                                       const int kernel_consumer,
631 +                                       const int edge, const int tsformat)
632 +{
633 +       /* LinuxPPS doesn't implement kernel consumer feature */
634 +       errno = EOPNOTSUPP;
635 +       return -1;
636 +}
637 +
638 +#endif                         /* _SYS_TIMEPPS_H_ */
639 --- a/MAINTAINERS
640 +++ b/MAINTAINERS
641 @@ -3011,6 +3011,13 @@
642  M:     jchapman@katalix.com
643  S:     Maintained
644  
645 +PPS SUPPORT
646 +P:     Rodolfo Giometti
647 +M:     giometti@enneenne.com
648 +W:     http://wiki.enneenne.com/index.php/LinuxPPS_support
649 +L:     linuxpps@ml.enneenne.com
650 +S:     Maintained
651 +
652  PREEMPTIBLE KERNEL
653  P:     Robert Love
654  M:     rml@tech9.net
655 --- a/drivers/Kconfig
656 +++ b/drivers/Kconfig
657 @@ -52,6 +52,8 @@
658  
659  source "drivers/spi/Kconfig"
660  
661 +source "drivers/pps/Kconfig"
662 +
663  source "drivers/w1/Kconfig"
664  
665  source "drivers/power/Kconfig"
666 --- a/drivers/Makefile
667 +++ b/drivers/Makefile
668 @@ -63,6 +63,7 @@
669  obj-$(CONFIG_I2O)              += message/
670  obj-$(CONFIG_RTC_LIB)          += rtc/
671  obj-y                          += i2c/
672 +obj-$(CONFIG_PPS)              += pps/
673  obj-$(CONFIG_W1)               += w1/
674  obj-$(CONFIG_POWER_SUPPLY)     += power/
675  obj-$(CONFIG_HWMON)            += hwmon/
676 --- a/drivers/char/lp.c
677 +++ b/drivers/char/lp.c
678 @@ -746,6 +746,27 @@
679  
680  #endif /* console on line printer */
681  
682 +/* Support for PPS signal on the line printer */
683 +
684 +#ifdef CONFIG_PPS_CLIENT_LP
685 +
686 +static void lp_pps_echo(int source, int event, void *data)
687 +{
688 +       struct parport *port = data;
689 +       unsigned char status = parport_read_status(port);
690 +
691 +       /* echo event via SEL bit */
692 +       parport_write_control(port,
693 +               parport_read_control(port) | PARPORT_CONTROL_SELECT);
694 +
695 +       /* signal no event */
696 +       if ((status & PARPORT_STATUS_ACK) != 0)
697 +               parport_write_control(port,
698 +                       parport_read_control(port) & ~PARPORT_CONTROL_SELECT);
699 +}
700 +
701 +#endif
702 +
703  /* --- initialisation code ------------------------------------- */
704  
705  static int parport_nr[LP_NO] = { [0 ... LP_NO-1] = LP_PARPORT_UNSPEC };
706 @@ -817,6 +838,38 @@
707         }
708  #endif
709  
710 +#ifdef CONFIG_PPS_CLIENT_LP
711 +       port->pps_info.owner = THIS_MODULE;
712 +       port->pps_info.dev = port->dev;
713 +       snprintf(port->pps_info.path, PPS_MAX_NAME_LEN, "/dev/lp%d", nr);
714 +
715 +       /* No PPS support if lp port has no IRQ line */
716 +       if (port->irq != PARPORT_IRQ_NONE) {
717 +               strncpy(port->pps_info.name, port->name, PPS_MAX_NAME_LEN);
718 +
719 +               port->pps_info.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \
720 +                               PPS_ECHOASSERT | \
721 +                               PPS_CANWAIT | PPS_TSFMT_TSPEC;
722 +
723 +               port->pps_info.echo = lp_pps_echo;
724 +
725 +               port->pps_source = pps_register_source(&(port->pps_info),
726 +                               PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
727 +               if (port->pps_source < 0)
728 +                       dev_err(port->dev,
729 +                                       "cannot register PPS source \"%s\"\n",
730 +                                       port->pps_info.path);
731 +               else
732 +                       dev_info(port->dev, "PPS source #%d \"%s\" added\n",
733 +                                       port->pps_source, port->pps_info.path);
734 +       } else {
735 +               port->pps_source = -1;
736 +               dev_err(port->dev, "PPS support disabled due port \"%s\" is "
737 +                                       "in polling mode\n",
738 +                                       port->pps_info.path);
739 +       }
740 +#endif
741 +
742         return 0;
743  }
744  
745 @@ -860,6 +913,14 @@
746                 console_registered = NULL;
747         }
748  #endif /* CONFIG_LP_CONSOLE */
749 +
750 +#ifdef CONFIG_PPS_CLIENT_LP
751 +       if (port->pps_source >= 0) {
752 +               pps_unregister_source(port->pps_source);
753 +               dev_dbg(port->dev, "PPS source #%d \"%s\" removed\n",
754 +                       port->pps_source, port->pps_info.path);
755 +       }
756 +#endif
757  }
758  
759  static struct parport_driver lp_driver = {
760 --- /dev/null
761 +++ b/drivers/pps/Kconfig
762 @@ -0,0 +1,34 @@
763 +#
764 +# PPS support configuration
765 +#
766 +
767 +menu "PPS support"
768 +
769 +config PPS
770 +       tristate "PPS support"
771 +       depends on EXPERIMENTAL
772 +       ---help---
773 +         PPS (Pulse Per Second) is a special pulse provided by some GPS
774 +         antennae. Userland can use it to get an high time reference.
775 +
776 +         Some antennae's PPS signals are connected with the CD (Carrier
777 +         Detect) pin of the serial line they use to communicate with the
778 +         host. In this case use the SERIAL_LINE client support.
779 +
780 +         Some antennae's PPS signals are connected with some special host
781 +         inputs so you have to enable the corresponding client support.
782 +
783 +         To compile this driver as a module, choose M here: the module
784 +         will be called pps_core.ko.
785 +
786 +config PPS_DEBUG
787 +       bool "PPS debugging messages"
788 +       depends on PPS 
789 +       help
790 +         Say Y here if you want the PPS support to produce a bunch of debug
791 +         messages to the system log.  Select this if you are having a
792 +         problem with PPS support and want to see more of what is going on.
793 +
794 +source drivers/pps/clients/Kconfig
795 +
796 +endmenu
797 --- /dev/null
798 +++ b/drivers/pps/Makefile
799 @@ -0,0 +1,11 @@
800 +#
801 +# Makefile for the PPS core.
802 +#
803 +
804 +pps_core-objs                  += pps.o kapi.o sysfs.o
805 +obj-$(CONFIG_PPS)              += pps_core.o
806 +obj-y                          += clients/
807 +
808 +ifeq ($(CONFIG_PPS_DEBUG),y)
809 +EXTRA_CFLAGS += -DDEBUG
810 +endif
811 --- /dev/null
812 +++ b/drivers/pps/clients/Kconfig
813 @@ -0,0 +1,38 @@
814 +#
815 +# PPS clients configuration
816 +#
817 +
818 +if PPS
819 +
820 +comment "PPS clients support"
821 +
822 +config PPS_CLIENT_KTIMER
823 +       tristate "Kernel timer client (Testing client, use for debug)"
824 +       help
825 +         If you say yes here you get support for a PPS debugging client
826 +         which uses a kernel timer to generate the PPS signal.
827 +
828 +         This driver can also be built as a module.  If so, the module
829 +         will be called ktimer.ko.
830 +
831 +comment "UART serial support (forced off)"
832 +       depends on ! (SERIAL_CORE != n && !(PPS = m && SERIAL_CORE = y))
833 +
834 +config PPS_CLIENT_UART
835 +       bool "UART serial support"
836 +       depends on SERIAL_CORE != n && !(PPS = m && SERIAL_CORE = y)
837 +       help
838 +         If you say yes here you get support for a PPS source connected
839 +         with the CD (Carrier Detect) pin of your serial port.
840 +
841 +comment "Parallel printer support (forced off)"
842 +       depends on !( PRINTER != n && !(PPS = m && PRINTER = y))
843 +
844 +config PPS_CLIENT_LP
845 +       bool "Parallel printer support"
846 +       depends on PRINTER != n && !(PPS = m && PRINTER = y)
847 +       help
848 +         If you say yes here you get support for a PPS source connected
849 +         with the interrupt pin of your parallel port.
850 +
851 +endif
852 --- /dev/null
853 +++ b/drivers/pps/clients/Makefile
854 @@ -0,0 +1,9 @@
855 +#
856 +# Makefile for PPS clients.
857 +#
858 +
859 +obj-$(CONFIG_PPS_CLIENT_KTIMER)        += ktimer.o
860 +
861 +ifeq ($(CONFIG_PPS_DEBUG),y)
862 +EXTRA_CFLAGS += -DDEBUG
863 +endif
864 --- /dev/null
865 +++ b/drivers/pps/clients/ktimer.c
866 @@ -0,0 +1,114 @@
867 +/*
868 + * ktimer.c -- kernel timer test client
869 + *
870 + *
871 + * Copyright (C) 2005-2006   Rodolfo Giometti <giometti@linux.it>
872 + *
873 + *   This program is free software; you can redistribute it and/or modify
874 + *   it under the terms of the GNU General Public License as published by
875 + *   the Free Software Foundation; either version 2 of the License, or
876 + *   (at your option) any later version.
877 + *
878 + *   This program is distributed in the hope that it will be useful,
879 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
880 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
881 + *   GNU General Public License for more details.
882 + *
883 + *   You should have received a copy of the GNU General Public License
884 + *   along with this program; if not, write to the Free Software
885 + *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
886 + */
887 +
888 +
889 +#include <linux/kernel.h>
890 +#include <linux/module.h>
891 +#include <linux/init.h>
892 +#include <linux/time.h>
893 +#include <linux/timer.h>
894 +
895 +#include <linux/pps.h>
896 +
897 +/*
898 + * Global variables
899 + */
900 +
901 +static int source;
902 +static struct timer_list ktimer;
903 +
904 +/*
905 + * The kernel timer
906 + */
907 +
908 +static void pps_ktimer_event(unsigned long ptr)
909 +{
910 +       pr_info("PPS event at %lu\n", jiffies);
911 +
912 +       pps_event(source, PPS_CAPTUREASSERT, NULL);
913 +
914 +       mod_timer(&ktimer, jiffies + HZ);
915 +}
916 +
917 +/*
918 + * The echo function
919 + */
920 +
921 +static void pps_ktimer_echo(int source, int event, void *data)
922 +{
923 +       pr_info("echo %s %s for source %d\n",
924 +               event & PPS_CAPTUREASSERT ? "assert" : "",
925 +               event & PPS_CAPTURECLEAR ? "clear" : "",
926 +               source);
927 +}
928 +
929 +/*
930 + * The PPS info struct
931 + */
932 +
933 +static struct pps_source_info pps_ktimer_info = {
934 +       name            : "ktimer",
935 +       path            : "",
936 +       mode            : PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \
937 +                         PPS_ECHOASSERT | \
938 +                         PPS_CANWAIT | PPS_TSFMT_TSPEC,
939 +       echo            : pps_ktimer_echo,
940 +       owner           : THIS_MODULE,
941 +};
942 +
943 +/*
944 + * Module staff
945 + */
946 +
947 +static void __exit pps_ktimer_exit(void)
948 +{
949 +       del_timer_sync(&ktimer);
950 +       pps_unregister_source(source);
951 +
952 +       pr_info("ktimer PPS source unregistered\n");
953 +}
954 +
955 +static int __init pps_ktimer_init(void)
956 +{
957 +       int ret;
958 +
959 +       ret = pps_register_source(&pps_ktimer_info,
960 +                               PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
961 +       if (ret < 0) {
962 +               printk(KERN_ERR "cannot register ktimer source\n");
963 +               return ret;
964 +       }
965 +       source = ret;
966 +
967 +       setup_timer(&ktimer, pps_ktimer_event, 0);
968 +       mod_timer(&ktimer, jiffies + HZ);
969 +
970 +       pr_info("ktimer PPS source registered at %d\n", source);
971 +
972 +       return  0;
973 +}
974 +
975 +module_init(pps_ktimer_init);
976 +module_exit(pps_ktimer_exit);
977 +
978 +MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
979 +MODULE_DESCRIPTION("dummy PPS source by using a kernel timer (just for debug)");
980 +MODULE_LICENSE("GPL");
981 --- /dev/null
982 +++ b/drivers/pps/kapi.c
983 @@ -0,0 +1,271 @@
984 +/*
985 + * kapi.c -- kernel API
986 + *
987 + *
988 + * Copyright (C) 2005-2007   Rodolfo Giometti <giometti@linux.it>
989 + *
990 + *   This program is free software; you can redistribute it and/or modify
991 + *   it under the terms of the GNU General Public License as published by
992 + *   the Free Software Foundation; either version 2 of the License, or
993 + *   (at your option) any later version.
994 + *
995 + *   This program is distributed in the hope that it will be useful,
996 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
997 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
998 + *   GNU General Public License for more details.
999 + *
1000 + *   You should have received a copy of the GNU General Public License
1001 + *   along with this program; if not, write to the Free Software
1002 + *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1003 + */
1004 +
1005 +
1006 +#include <linux/kernel.h>
1007 +#include <linux/module.h>
1008 +#include <linux/init.h>
1009 +#include <linux/sched.h>
1010 +#include <linux/time.h>
1011 +#include <linux/spinlock.h>
1012 +#include <linux/idr.h>
1013 +#include <linux/fs.h>
1014 +#include <linux/pps.h>
1015 +
1016 +/*
1017 + * Local variables
1018 + */
1019 +
1020 +static spinlock_t idr_lock = SPIN_LOCK_UNLOCKED;
1021 +static DEFINE_IDR(pps_idr);
1022 +
1023 +/*
1024 + * Local functions
1025 + */
1026 +
1027 +static void pps_add_offset(struct pps_ktime *ts, struct pps_ktime *offset)
1028 +{
1029 +       ts->nsec += offset->nsec;
1030 +       if (ts->nsec >= NSEC_PER_SEC) {
1031 +               ts->nsec -= NSEC_PER_SEC;
1032 +               ts->sec++;
1033 +       } else if (ts->nsec < 0) {
1034 +               ts->nsec += NSEC_PER_SEC;
1035 +               ts->sec--;
1036 +       }
1037 +       ts->sec += offset->sec;
1038 +}
1039 +
1040 +/*
1041 + * Exported functions
1042 + */
1043 +
1044 +int pps_register_source(struct pps_source_info *info, int default_params)
1045 +{
1046 +       struct pps_device *pps;
1047 +       int id;
1048 +       int err;
1049 +
1050 +       /* Sanity checks */
1051 +       if ((info->mode & default_params) != default_params) {
1052 +               printk(KERN_ERR "pps: %s: unsupported default parameters\n",
1053 +                                       info->name);
1054 +               err = -EINVAL;
1055 +               goto pps_register_source_exit;
1056 +       }
1057 +       if ((info->mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) != 0 &&
1058 +                       info->echo == NULL) {
1059 +               printk(KERN_ERR "pps: %s: echo function is not defined\n",
1060 +                                       info->name);
1061 +               err = -EINVAL;
1062 +               goto pps_register_source_exit;
1063 +       }
1064 +       if ((info->mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
1065 +               printk(KERN_ERR "pps: %s: unspecified time format\n",
1066 +                                       info->name);
1067 +               err = -EINVAL;
1068 +               goto pps_register_source_exit;
1069 +       }
1070 +
1071 +       /* Allocate memory for the new PPS source struct */
1072 +       pps = kzalloc(sizeof(struct pps_device), GFP_KERNEL);
1073 +       if (pps == NULL) {
1074 +               err = -ENOMEM;
1075 +               goto pps_register_source_exit;
1076 +       }
1077 +
1078 +       /* Get new ID for the new PPS source */
1079 +       if (idr_pre_get(&pps_idr, GFP_KERNEL) == 0) {
1080 +               err = -ENOMEM;
1081 +               goto kfree_pps;
1082 +       }
1083 +
1084 +       spin_lock_irq(&idr_lock);
1085 +       err = idr_get_new(&pps_idr, pps, &id);
1086 +       spin_unlock_irq(&idr_lock);
1087 +
1088 +       if (err < 0)
1089 +               goto kfree_pps;
1090 +
1091 +       id = id & MAX_ID_MASK;
1092 +       if (id >= PPS_MAX_SOURCES) {
1093 +               printk(KERN_ERR "pps: %s: too much PPS sources in the system\n",
1094 +                                       info->name);
1095 +               err = -EBUSY;
1096 +               goto free_idr;
1097 +       }
1098 +
1099 +       pps->id = id;
1100 +       pps->params.api_version = PPS_API_VERS;
1101 +       pps->params.mode = default_params;
1102 +       pps->info = *info;
1103 +
1104 +       init_waitqueue_head(&pps->queue);
1105 +       spin_lock_init(&pps->lock);
1106 +       atomic_set(&pps->usage, 0);
1107 +       init_waitqueue_head(&pps->usage_queue);
1108 +
1109 +       /* Create the char device */
1110 +       err = pps_register_cdev(pps);
1111 +       if (err < 0) {
1112 +               printk(KERN_ERR "pps: %s: unable to create char device\n",
1113 +                                       info->name);
1114 +               goto free_idr;
1115 +       }
1116 +
1117 +       /* Create the sysfs entry */
1118 +       err = pps_sysfs_create_source_entry(pps);
1119 +       if (err < 0) {
1120 +               printk(KERN_ERR "pps: %s: unable to create sysfs entries\n",
1121 +                                       info->name);
1122 +               goto unregister_cdev;
1123 +       }
1124 +
1125 +       pr_info("new PPS source %s at ID %d\n", info->name, id);
1126 +
1127 +       return id;
1128 +
1129 +unregister_cdev:
1130 +       pps_unregister_cdev(pps);
1131 +
1132 +free_idr:
1133 +       spin_lock_irq(&idr_lock);
1134 +       idr_remove(&pps_idr, id);
1135 +       spin_unlock_irq(&idr_lock);
1136 +
1137 +kfree_pps:
1138 +       kfree(pps);
1139 +
1140 +pps_register_source_exit:
1141 +       printk(KERN_ERR "pps: %s: unable to register source\n", info->name);
1142 +
1143 +       return err;
1144 +}
1145 +EXPORT_SYMBOL(pps_register_source);
1146 +
1147 +void pps_unregister_source(int source)
1148 +{
1149 +       struct pps_device *pps;
1150 +
1151 +       spin_lock_irq(&idr_lock);
1152 +       pps = idr_find(&pps_idr, source);
1153 +
1154 +       if (!pps) {
1155 +               spin_unlock_irq(&idr_lock);
1156 +               return;
1157 +       }
1158 +
1159 +       /* This should be done first in order to deny IRQ handlers
1160 +        * to access PPS structs
1161 +        */
1162 +
1163 +       idr_remove(&pps_idr, pps->id);
1164 +       spin_unlock_irq(&idr_lock);
1165 +
1166 +       wait_event(pps->usage_queue, atomic_read(&pps->usage) == 0);
1167 +
1168 +       pps_sysfs_remove_source_entry(pps);
1169 +       pps_unregister_cdev(pps);
1170 +       kfree(pps);
1171 +}
1172 +EXPORT_SYMBOL(pps_unregister_source);
1173 +
1174 +void pps_event(int source, int event, void *data)
1175 +{
1176 +       struct pps_device *pps;
1177 +       struct timespec __ts;
1178 +       struct pps_ktime ts;
1179 +       unsigned long flags;
1180 +
1181 +       /* First of all we get the time stamp... */
1182 +       getnstimeofday(&__ts);
1183 +
1184 +       /* ... and translate it to PPS time data struct */
1185 +       ts.sec = __ts.tv_sec;
1186 +       ts.nsec = __ts.tv_nsec;
1187 +
1188 +       if ((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0 ) {
1189 +               printk(KERN_ERR "pps: unknown event (%x) for source %d\n",
1190 +                       event, source);
1191 +               return;
1192 +       }
1193 +
1194 +       spin_lock_irqsave(&idr_lock, flags);
1195 +       pps = idr_find(&pps_idr, source);
1196 +
1197 +       /* If we find a valid PPS source we lock it before leaving
1198 +        * the lock!
1199 +        */
1200 +       if (pps)
1201 +               atomic_inc(&pps->usage);
1202 +       spin_unlock_irqrestore(&idr_lock, flags);
1203 +
1204 +       if (!pps)
1205 +               return;
1206 +
1207 +       pr_debug("PPS event on source %d at at %llu.%06u\n",
1208 +                       pps->id, ts.sec, ts.nsec);
1209 +
1210 +       spin_lock_irqsave(&pps->lock, flags);
1211 +
1212 +       /* Must call the echo function? */
1213 +       if ((pps->params.mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)))
1214 +               pps->info.echo(source, event, data);
1215 +
1216 +       /* Check the event */
1217 +       pps->current_mode = pps->params.mode;
1218 +       if (event & PPS_CAPTUREASSERT) {
1219 +               /* We have to add an offset? */
1220 +               if (pps->params.mode & PPS_OFFSETASSERT)
1221 +                       pps_add_offset(&ts, &pps->params.assert_off_tu);
1222 +
1223 +               /* Save the time stamp */
1224 +               pps->assert_tu = ts;
1225 +               pps->assert_sequence++;
1226 +               pr_debug("capture assert seq #%u for source %d\n",
1227 +                       pps->assert_sequence, source);
1228 +       }
1229 +       if (event & PPS_CAPTURECLEAR) {
1230 +               /* We have to add an offset? */
1231 +               if (pps->params.mode & PPS_OFFSETCLEAR)
1232 +                       pps_add_offset(&ts, &pps->params.clear_off_tu);
1233 +
1234 +               /* Save the time stamp */
1235 +               pps->clear_tu = ts;
1236 +               pps->clear_sequence++;
1237 +               pr_debug("capture clear seq #%u for source %d\n",
1238 +                       pps->clear_sequence, source);
1239 +       }
1240 +
1241 +       pps->go = ~0;
1242 +       wake_up_interruptible(&pps->queue);
1243 +
1244 +       kill_fasync(&pps->async_queue, SIGIO, POLL_IN);
1245 +
1246 +       spin_unlock_irqrestore(&pps->lock, flags);
1247 +
1248 +       /* Now we can release the PPS source for (possible) deregistration */
1249 +       spin_lock_irqsave(&idr_lock, flags);
1250 +       atomic_dec(&pps->usage);
1251 +       wake_up_all(&pps->usage_queue);
1252 +       spin_unlock_irqrestore(&idr_lock, flags);
1253 +}
1254 +EXPORT_SYMBOL(pps_event);
1255 --- /dev/null
1256 +++ b/drivers/pps/pps.c
1257 @@ -0,0 +1,332 @@
1258 +/*
1259 + * pps.c -- Main PPS support file
1260 + *
1261 + *
1262 + * Copyright (C) 2005-2007   Rodolfo Giometti <giometti@linux.it>
1263 + *
1264 + *   This program is free software; you can redistribute it and/or modify
1265 + *   it under the terms of the GNU General Public License as published by
1266 + *   the Free Software Foundation; either version 2 of the License, or
1267 + *   (at your option) any later version.
1268 + *
1269 + *   This program is distributed in the hope that it will be useful,
1270 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1271 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1272 + *   GNU General Public License for more details.
1273 + *
1274 + *   You should have received a copy of the GNU General Public License
1275 + *   along with this program; if not, write to the Free Software
1276 + *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1277 + */
1278 +
1279 +
1280 +#include <linux/kernel.h>
1281 +#include <linux/version.h>
1282 +#include <linux/module.h>
1283 +#include <linux/init.h>
1284 +#include <linux/sched.h>
1285 +#include <linux/uaccess.h>
1286 +#include <linux/cdev.h>
1287 +#include <linux/poll.h>
1288 +#include <linux/pps.h>
1289 +
1290 +/*
1291 + * Local variables
1292 + */
1293 +
1294 +static dev_t pps_devt;
1295 +static struct class *pps_class;
1296 +
1297 +/*
1298 + * Char device methods
1299 + */
1300 +
1301 +static unsigned int pps_cdev_poll(struct file *file, poll_table *wait)
1302 +{
1303 +       struct pps_device *pps = file->private_data;
1304 +
1305 +       poll_wait(file, &pps->queue, wait);
1306 +
1307 +       return POLLIN | POLLRDNORM;
1308 +}
1309 +
1310 +static int pps_cdev_fasync(int fd, struct file *file, int on)
1311 +{
1312 +       struct pps_device *pps = file->private_data;
1313 +       return fasync_helper(fd, file, on, &pps->async_queue);
1314 +}
1315 +
1316 +static int pps_cdev_ioctl(struct inode *inode, struct file *file,
1317 +               unsigned int cmd, unsigned long arg)
1318 +{
1319 +       struct pps_device *pps = file->private_data;
1320 +       struct pps_kparams params;
1321 +       struct pps_fdata fdata;
1322 +       unsigned long ticks;
1323 +       void __user *uarg = (void __user *) arg;
1324 +       int __user *iuarg = (int __user *) arg;
1325 +       int err;
1326 +
1327 +       switch (cmd) {
1328 +       case PPS_CHECK:
1329 +
1330 +               /* This does nothing but signal we are a PPS source... */
1331 +
1332 +               return 0;
1333 +
1334 +       case PPS_GETPARAMS:
1335 +               pr_debug("PPS_GETPARAMS: source %d\n", pps->id);
1336 +
1337 +               /* Sanity checks */
1338 +               if (!uarg)
1339 +                       return -EINVAL;
1340 +
1341 +               /* Return current parameters */
1342 +               err = copy_to_user(uarg, &pps->params,
1343 +                                               sizeof(struct pps_kparams));
1344 +               if (err)
1345 +                       return -EFAULT;
1346 +
1347 +               break;
1348 +
1349 +       case PPS_SETPARAMS:
1350 +               pr_debug("PPS_SETPARAMS: source %d\n", pps->id);
1351 +
1352 +               /* Check the capabilities */
1353 +               if (!capable(CAP_SYS_TIME))
1354 +                       return -EPERM;
1355 +
1356 +               /* Sanity checks */
1357 +               if (!uarg)
1358 +                       return -EINVAL;
1359 +               err = copy_from_user(&params, uarg, sizeof(struct pps_kparams));
1360 +               if (err)
1361 +                       return -EFAULT;
1362 +               if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) {
1363 +                       pr_debug("capture mode unspecified (%x)\n",
1364 +                                                               params.mode);
1365 +                       return -EINVAL;
1366 +               }
1367 +
1368 +               /* Check for supported capabilities */
1369 +               if ((params.mode & ~pps->info.mode) != 0) {
1370 +                       pr_debug("unsupported capabilities (%x)\n",
1371 +                                                               params.mode);
1372 +                       return -EINVAL;
1373 +               }
1374 +
1375 +               spin_lock_irq(&pps->lock);
1376 +
1377 +               /* Save the new parameters */
1378 +               pps->params = params;
1379 +
1380 +               /* Restore the read only parameters */
1381 +               if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
1382 +                       /* section 3.3 of RFC 2783 interpreted */
1383 +                       pr_debug("time format unspecified (%x)\n",
1384 +                                                               params.mode);
1385 +                       pps->params.mode |= PPS_TSFMT_TSPEC;
1386 +               }
1387 +               if (pps->info.mode & PPS_CANWAIT)
1388 +                       pps->params.mode |= PPS_CANWAIT;
1389 +               pps->params.api_version = PPS_API_VERS;
1390 +
1391 +               spin_unlock_irq(&pps->lock);
1392 +
1393 +               break;
1394 +
1395 +       case PPS_GETCAP:
1396 +               pr_debug("PPS_GETCAP: source %d\n", pps->id);
1397 +
1398 +               /* Sanity checks */
1399 +               if (!uarg)
1400 +                       return -EINVAL;
1401 +
1402 +               err = put_user(pps->info.mode, iuarg);
1403 +               if (err)
1404 +                       return -EFAULT;
1405 +
1406 +               break;
1407 +
1408 +       case PPS_FETCH:
1409 +               pr_debug("PPS_FETCH: source %d\n", pps->id);
1410 +
1411 +               if (!uarg)
1412 +                       return -EINVAL;
1413 +               err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata));
1414 +               if (err)
1415 +                       return -EFAULT;
1416 +
1417 +               pps->go = 0;
1418 +
1419 +               /* Manage the timeout */
1420 +               if (fdata.timeout.flags & PPS_TIME_INVALID)
1421 +                       err = wait_event_interruptible(pps->queue, pps->go);
1422 +               else {
1423 +                       pr_debug("timeout %lld.%09d\n",
1424 +                                       fdata.timeout.sec, fdata.timeout.nsec);
1425 +                       ticks = fdata.timeout.sec * HZ;
1426 +                       ticks += fdata.timeout.nsec / (NSEC_PER_SEC / HZ);
1427 +
1428 +                       if (ticks != 0) {
1429 +                               err = wait_event_interruptible_timeout(
1430 +                                               pps->queue, pps->go, ticks);
1431 +                               if (err == 0)
1432 +                                       return -ETIMEDOUT;
1433 +                       }
1434 +               }
1435 +
1436 +               /* Check for pending signals */
1437 +               if (err == -ERESTARTSYS) {
1438 +                       pr_debug("pending signal caught\n");
1439 +                       return -EINTR;
1440 +               }
1441 +
1442 +               /* Return the fetched timestamp */
1443 +               spin_lock_irq(&pps->lock);
1444 +
1445 +               fdata.info.assert_sequence = pps->assert_sequence;
1446 +               fdata.info.clear_sequence = pps->clear_sequence;
1447 +               fdata.info.assert_tu = pps->assert_tu;
1448 +               fdata.info.clear_tu = pps->clear_tu;
1449 +               fdata.info.current_mode = pps->current_mode;
1450 +
1451 +               spin_unlock_irq(&pps->lock);
1452 +
1453 +               err = copy_to_user(uarg, &fdata, sizeof(struct pps_fdata));
1454 +               if (err)
1455 +                       return -EFAULT;
1456 +
1457 +               break;
1458 +
1459 +       default:
1460 +               return -ENOTTY;
1461 +               break;
1462 +       }
1463 +
1464 +       return 0;
1465 +}
1466 +
1467 +static int pps_cdev_open(struct inode *inode, struct file *file)
1468 +{
1469 +       struct pps_device *pps = container_of(inode->i_cdev,
1470 +                                               struct pps_device, cdev);
1471 +
1472 +       /* Lock the PPS source against (possible) deregistration */
1473 +       atomic_inc(&pps->usage);
1474 +
1475 +       file->private_data = pps;
1476 +
1477 +       return 0;
1478 +}
1479 +
1480 +static int pps_cdev_release(struct inode *inode, struct file *file)
1481 +{
1482 +       struct pps_device *pps = file->private_data;
1483 +
1484 +       /* Free the PPS source and wake up (possible) deregistration */
1485 +       atomic_dec(&pps->usage);
1486 +       wake_up_all(&pps->usage_queue);
1487 +
1488 +       return 0;
1489 +}
1490 +
1491 +/*
1492 + * Char device stuff
1493 + */
1494 +
1495 +static const struct file_operations pps_cdev_fops = {
1496 +       .owner          = THIS_MODULE,
1497 +       .llseek         = no_llseek,
1498 +       .poll           = pps_cdev_poll,
1499 +       .fasync         = pps_cdev_fasync,
1500 +       .ioctl          = pps_cdev_ioctl,
1501 +       .open           = pps_cdev_open,
1502 +       .release        = pps_cdev_release,
1503 +};
1504 +
1505 +int pps_register_cdev(struct pps_device *pps)
1506 +{
1507 +       int err;
1508 +
1509 +       pps->devno = MKDEV(MAJOR(pps_devt), pps->id);
1510 +       cdev_init(&pps->cdev, &pps_cdev_fops);
1511 +       pps->cdev.owner = pps->info.owner;
1512 +
1513 +       err = cdev_add(&pps->cdev, pps->devno, 1);
1514 +       if (err) {
1515 +               printk(KERN_ERR "pps: %s: failed to add char device %d:%d\n",
1516 +                               pps->info.name, MAJOR(pps_devt), pps->id);
1517 +               return err;
1518 +       }
1519 +       pps->dev = device_create(pps_class, pps->info.dev, pps->devno,
1520 +                                                       "pps%d", pps->id);
1521 +       if (err)
1522 +               goto del_cdev;
1523 +       dev_set_drvdata(pps->dev, pps);
1524 +
1525 +       pr_debug("source %s got cdev (%d:%d)\n", pps->info.name,
1526 +                       MAJOR(pps_devt), pps->id);
1527 +
1528 +       return 0;
1529 +
1530 +del_cdev:
1531 +       cdev_del(&pps->cdev);
1532 +
1533 +       return err;
1534 +}
1535 +
1536 +void pps_unregister_cdev(struct pps_device *pps)
1537 +{
1538 +       device_destroy(pps_class, pps->devno);
1539 +       cdev_del(&pps->cdev);
1540 +}
1541 +
1542 +/*
1543 + * Module staff
1544 + */
1545 +
1546 +static void __exit pps_exit(void)
1547 +{
1548 +       class_destroy(pps_class);
1549 +
1550 +       if (pps_devt)
1551 +               unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES);
1552 +
1553 +       pr_info("LinuxPPS API ver. %d removed\n", PPS_API_VERS);
1554 +}
1555 +
1556 +static int __init pps_init(void)
1557 +{
1558 +       int err;
1559 +
1560 +       pps_class = class_create(THIS_MODULE, "pps");
1561 +       if (!pps_class) {
1562 +               printk(KERN_ERR "pps: ailed to allocate class\n");
1563 +               return -ENOMEM;
1564 +       }
1565 +
1566 +       err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps");
1567 +       if (err < 0) {
1568 +               printk(KERN_ERR "pps: failed to allocate char device region\n");
1569 +               goto remove_class;
1570 +       }
1571 +
1572 +       pr_info("LinuxPPS API ver. %d registered\n", PPS_API_VERS);
1573 +       pr_info("Software ver. %s - Copyright 2005-2007 Rodolfo Giometti "
1574 +               "<giometti@linux.it>\n", PPS_VERSION);
1575 +
1576 +       return 0;
1577 +
1578 +remove_class:
1579 +       class_destroy(pps_class);
1580 +
1581 +       return err;
1582 +}
1583 +
1584 +subsys_initcall(pps_init);
1585 +module_exit(pps_exit);
1586 +
1587 +MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
1588 +MODULE_DESCRIPTION("LinuxPPS support (RFC 2783) - ver. " PPS_VERSION);
1589 +MODULE_LICENSE("GPL");
1590 --- /dev/null
1591 +++ b/drivers/pps/sysfs.c
1592 @@ -0,0 +1,124 @@
1593 +/*
1594 + * sysfs.c -- sysfs support
1595 + *
1596 + *
1597 + * Copyright (C) 2007   Rodolfo Giometti <giometti@linux.it>
1598 + *
1599 + *   This program is free software; you can redistribute it and/or modify
1600 + *   it under the terms of the GNU General Public License as published by
1601 + *   the Free Software Foundation; either version 2 of the License, or
1602 + *   (at your option) any later version.
1603 + *
1604 + *   This program is distributed in the hope that it will be useful,
1605 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1606 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1607 + *   GNU General Public License for more details.
1608 + *
1609 + *   You should have received a copy of the GNU General Public License
1610 + *   along with this program; if not, write to the Free Software
1611 + *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1612 + */
1613 +
1614 +
1615 +#include <linux/device.h>
1616 +#include <linux/module.h>
1617 +#include <linux/string.h>
1618 +#include <linux/pps.h>
1619 +
1620 +/*
1621 + * Attribute functions
1622 + */
1623 +
1624 +static ssize_t pps_show_assert(struct device *dev,
1625 +                               struct device_attribute *attr, char *buf)
1626 +{
1627 +       struct pps_device *pps = dev_get_drvdata(dev);
1628 +
1629 +       return sprintf(buf, "%lld.%09d#%d\n",
1630 +                       pps->assert_tu.sec, pps->assert_tu.nsec,
1631 +                       pps->assert_sequence);
1632 +}
1633 +DEVICE_ATTR(assert, S_IRUGO, pps_show_assert, NULL);
1634 +
1635 +static ssize_t pps_show_clear(struct device *dev,
1636 +                               struct device_attribute *attr, char *buf)
1637 +{
1638 +       struct pps_device *pps = dev_get_drvdata(dev);
1639 +
1640 +       return sprintf(buf, "%lld.%09d#%d\n",
1641 +                       pps->clear_tu.sec, pps->clear_tu.nsec,
1642 +                       pps->clear_sequence);
1643 +}
1644 +DEVICE_ATTR(clear, S_IRUGO, pps_show_clear, NULL);
1645 +
1646 +static ssize_t pps_show_mode(struct device *dev,
1647 +                               struct device_attribute *attr, char *buf)
1648 +{
1649 +       struct pps_device *pps = dev_get_drvdata(dev);
1650 +
1651 +       return sprintf(buf, "%4x\n", pps->info.mode);
1652 +}
1653 +DEVICE_ATTR(mode, S_IRUGO, pps_show_mode, NULL);
1654 +
1655 +static ssize_t pps_show_echo(struct device *dev,
1656 +                               struct device_attribute *attr, char *buf)
1657 +{
1658 +       struct pps_device *pps = dev_get_drvdata(dev);
1659 +
1660 +       return sprintf(buf, "%d\n", !!pps->info.echo);
1661 +}
1662 +DEVICE_ATTR(echo, S_IRUGO, pps_show_echo, NULL);
1663 +
1664 +static ssize_t pps_show_name(struct device *dev,
1665 +                               struct device_attribute *attr, char *buf)
1666 +{
1667 +       struct pps_device *pps = dev_get_drvdata(dev);
1668 +
1669 +       return sprintf(buf, "%s\n", pps->info.name);
1670 +}
1671 +DEVICE_ATTR(name, S_IRUGO, pps_show_name, NULL);
1672 +
1673 +static ssize_t pps_show_path(struct device *dev,
1674 +                               struct device_attribute *attr, char *buf)
1675 +{
1676 +       struct pps_device *pps = dev_get_drvdata(dev);
1677 +
1678 +       return sprintf(buf, "%s\n", pps->info.path);
1679 +}
1680 +DEVICE_ATTR(path, S_IRUGO, pps_show_path, NULL);
1681 +
1682 +/*
1683 + * Public functions
1684 + */
1685 +
1686 +void pps_sysfs_remove_source_entry(struct pps_device *pps)
1687 +{
1688 +       /* Delete info files */
1689 +       if (pps->info.mode & PPS_CAPTUREASSERT)
1690 +               device_remove_file(pps->dev, &dev_attr_assert);
1691 +
1692 +       if (pps->info.mode & PPS_CAPTURECLEAR)
1693 +               device_remove_file(pps->dev, &dev_attr_clear);
1694 +
1695 +       device_remove_file(pps->dev, &dev_attr_mode);
1696 +       device_remove_file(pps->dev, &dev_attr_echo);
1697 +       device_remove_file(pps->dev, &dev_attr_name);
1698 +       device_remove_file(pps->dev, &dev_attr_path);
1699 +}
1700 +
1701 +int pps_sysfs_create_source_entry(struct pps_device *pps)
1702 +{
1703 +       /* Create file "assert" and "clear" according to source capability */
1704 +       if (pps->info.mode & PPS_CAPTUREASSERT)
1705 +               device_create_file(pps->dev, &dev_attr_assert);
1706 +
1707 +       if (pps->info.mode & PPS_CAPTURECLEAR)
1708 +               device_create_file(pps->dev, &dev_attr_clear);
1709 +
1710 +       device_create_file(pps->dev, &dev_attr_mode);
1711 +       device_create_file(pps->dev, &dev_attr_echo);
1712 +       device_create_file(pps->dev, &dev_attr_name);
1713 +       device_create_file(pps->dev, &dev_attr_path);
1714 +
1715 +       return 0;
1716 +}
1717 --- a/drivers/serial/8250.c
1718 +++ b/drivers/serial/8250.c
1719 @@ -2118,6 +2118,8 @@
1720                 up->ier |= UART_IER_MSI;
1721         if (up->capabilities & UART_CAP_UUE)
1722                 up->ier |= UART_IER_UUE | UART_IER_RTOIE;
1723 +       if (up->port.flags & UPF_HARDPPS_CD)
1724 +               up->ier |= UART_IER_MSI;        /* enable interrupts */
1725  
1726         serial_out(up, UART_IER, up->ier);
1727  
1728 --- a/drivers/serial/serial_core.c
1729 +++ b/drivers/serial/serial_core.c
1730 @@ -33,6 +33,7 @@
1731  #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
1732  #include <linux/delay.h>
1733  #include <linux/mutex.h>
1734 +#include <linux/pps.h>
1735  
1736  #include <asm/irq.h>
1737  #include <asm/uaccess.h>
1738 @@ -633,6 +634,54 @@
1739         return 0;
1740  }
1741  
1742 +#ifdef CONFIG_PPS_CLIENT_UART
1743 +
1744 +static int
1745 +uart_register_pps_port(struct uart_state *state, struct uart_port *port)
1746 +{
1747 +       struct tty_driver *drv = port->info->tty->driver;
1748 +       int ret;
1749 +
1750 +       state->pps_info.owner = THIS_MODULE;
1751 +       state->pps_info.dev = port->dev;
1752 +       snprintf(state->pps_info.name, PPS_MAX_NAME_LEN, "%s%d",
1753 +               drv->driver_name, port->line);
1754 +       snprintf(state->pps_info.path, PPS_MAX_NAME_LEN, "/dev/%s%d",
1755 +               drv->name, port->line);
1756 +
1757 +       state->pps_info.mode = PPS_CAPTUREBOTH | \
1758 +                       PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
1759 +                       PPS_CANWAIT | PPS_TSFMT_TSPEC;
1760 +
1761 +       ret = pps_register_source(&state->pps_info, PPS_CAPTUREBOTH | \
1762 +                               PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
1763 +       if (ret < 0) {
1764 +               dev_err(port->dev, "cannot register PPS source \"%s\"\n",
1765 +                                               state->pps_info.path);
1766 +               return ret;
1767 +       }
1768 +       port->pps_source = ret;
1769 +       dev_dbg(port->dev, "PPS source #%d \"%s\" added\n",
1770 +               port->pps_source, state->pps_info.path);
1771 +
1772 +       return 0;
1773 +}
1774 +
1775 +static void
1776 +uart_unregister_pps_port(struct uart_state *state, struct uart_port *port)
1777 +{
1778 +       pps_unregister_source(port->pps_source);
1779 +       dev_dbg(port->dev, "PPS source #%d \"%s\" removed\n",
1780 +                               port->pps_source, state->pps_info.path);
1781 +}
1782 +
1783 +#else
1784 +
1785 +#define uart_register_pps_port(state, port)    do { } while (0)
1786 +#define uart_unregister_pps_port(state, port)  do { } while (0)
1787 +
1788 +#endif /* CONFIG_PPS_CLIENT_UART */
1789 +
1790  static int uart_set_info(struct uart_state *state,
1791                          struct serial_struct __user *newinfo)
1792  {
1793 @@ -807,11 +856,19 @@
1794                         (port->flags & UPF_LOW_LATENCY) ? 1 : 0;
1795  
1796   check_and_exit:
1797 +       /* PPS support enabled/disabled? */
1798 +       if ((old_flags & UPF_HARDPPS_CD) != (new_flags & UPF_HARDPPS_CD)) {
1799 +               if (new_flags & UPF_HARDPPS_CD)
1800 +                       uart_register_pps_port(state, port);
1801 +               else
1802 +                       uart_unregister_pps_port(state, port);
1803 +       }
1804 +
1805         retval = 0;
1806         if (port->type == PORT_UNKNOWN)
1807                 goto exit;
1808         if (state->info->flags & UIF_INITIALIZED) {
1809 -               if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
1810 +               if (((old_flags ^ port->flags) & (UPF_SPD_MASK|UPF_HARDPPS_CD)) ||
1811                     old_custom_divisor != port->custom_divisor) {
1812                         /*
1813                          * If they're setting up a custom divisor or speed,
1814 @@ -2110,6 +2167,12 @@
1815                 port->ops->config_port(port, flags);
1816         }
1817  
1818 +       /*
1819 +        * Add the PPS support for the current port.
1820 +        */
1821 +       if (port->flags & UPF_HARDPPS_CD)
1822 +               uart_register_pps_port(state, port);
1823 +
1824         if (port->type != PORT_UNKNOWN) {
1825                 unsigned long flags;
1826  
1827 @@ -2359,6 +2422,12 @@
1828         mutex_unlock(&state->mutex);
1829  
1830         /*
1831 +        * Remove PPS support from the current port.
1832 +        */
1833 +       if (port->flags & UPF_HARDPPS_CD)
1834 +               uart_unregister_pps_port(state, port);
1835 +
1836 +       /*
1837          * Remove the devices from the tty layer
1838          */
1839         tty_unregister_device(drv->tty_driver, port->line);
1840 --- a/include/linux/Kbuild
1841 +++ b/include/linux/Kbuild
1842 @@ -295,6 +295,7 @@
1843  unifdef-y += poll.h
1844  unifdef-y += ppp_defs.h
1845  unifdef-y += ppp-comp.h
1846 +unifdef-y += pps.h
1847  unifdef-y += ptrace.h
1848  unifdef-y += qnx4_fs.h
1849  unifdef-y += quota.h
1850 --- a/include/linux/parport.h
1851 +++ b/include/linux/parport.h
1852 @@ -100,6 +100,7 @@
1853  #include <linux/proc_fs.h>
1854  #include <linux/spinlock.h>
1855  #include <linux/wait.h>
1856 +#include <linux/pps.h>
1857  #include <asm/system.h>
1858  #include <asm/ptrace.h>
1859  #include <asm/semaphore.h>
1860 @@ -327,6 +328,11 @@
1861  
1862         struct list_head full_list;
1863         struct parport *slaves[3];
1864 +
1865 +#ifdef CONFIG_PPS_CLIENT_LP
1866 +       struct pps_source_info pps_info;
1867 +       int pps_source;         /* PPS source ID */
1868 +#endif
1869  };
1870  
1871  #define DEFAULT_SPIN_TIME 500 /* us */
1872 @@ -517,6 +523,12 @@
1873  /* Lowlevel drivers _can_ call this support function to handle irqs.  */
1874  static __inline__ void parport_generic_irq(int irq, struct parport *port)
1875  {
1876 +#ifdef CONFIG_PPS_CLIENT_LP
1877 +       pps_event(port->pps_source, PPS_CAPTUREASSERT, port);
1878 +       dev_dbg(port->dev, "PPS assert at %lu on source #%d\n",
1879 +               jiffies, port->pps_source);
1880 +#endif
1881 +
1882         parport_ieee1284_interrupt (irq, port);
1883         read_lock(&port->cad_lock);
1884         if (port->cad && port->cad->irq_func)
1885 --- /dev/null
1886 +++ b/include/linux/pps.h
1887 @@ -0,0 +1,196 @@
1888 +/*
1889 + * pps.h -- PPS API kernel header.
1890 + *
1891 + *
1892 + * Copyright (C) 2005-2007   Rodolfo Giometti <giometti@linux.it>
1893 + *
1894 + *   This program is free software; you can redistribute it and/or modify
1895 + *   it under the terms of the GNU General Public License as published by
1896 + *   the Free Software Foundation; either version 2 of the License, or
1897 + *   (at your option) any later version.
1898 + *
1899 + *   This program is distributed in the hope that it will be useful,
1900 + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
1901 + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1902 + *   GNU General Public License for more details.
1903 + *
1904 + *   You should have received a copy of the GNU General Public License
1905 + *   along with this program; if not, write to the Free Software
1906 + *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1907 + */
1908 +
1909 +
1910 +#ifndef _PPS_H_
1911 +#define _PPS_H_
1912 +
1913 +/* Implementation note: the logical states ``assert'' and ``clear''
1914 + * are implemented in terms of the chip register, i.e. ``assert''
1915 + * means the bit is set.  */
1916 +
1917 +/*
1918 + * 3.2 New data structures
1919 + */
1920 +
1921 +#ifndef __KERNEL__
1922 +#include <linux/types.h>
1923 +#include <sys/time.h>
1924 +#include <sys/ioctl.h>
1925 +#else
1926 +#include <linux/time.h>
1927 +#endif
1928 +
1929 +#define PPS_API_VERS           1
1930 +#define PPS_MAX_NAME_LEN       32
1931 +
1932 +/* 32-bit vs. 64-bit compatibility.
1933 + *
1934 + * 0n i386, the alignment of a uint64_t is only 4 bytes, while on most other
1935 + * architectures it's 8 bytes. On i386, there will be no padding between the
1936 + * two consecutive 'struct pps_ktime' members of struct pps_kinfo and struct
1937 + * pps_kparams. But on most platforms there will be padding to ensure correct
1938 + * alignment.
1939 + *
1940 + * The simple fix is probably to add an explicit padding.
1941 + *                                                     [David Woodhouse]
1942 + */
1943 +struct pps_ktime {
1944 +       __u64 sec;
1945 +       __u32 nsec;
1946 +       __u32 flags;
1947 +};
1948 +#define PPS_TIME_INVALID       (1<<0)  /* used to specify timeout==NULL */
1949 +
1950 +struct pps_kinfo {
1951 +       __u32 assert_sequence;          /* seq. num. of assert event */
1952 +       __u32 clear_sequence;           /* seq. num. of clear event */
1953 +       struct pps_ktime assert_tu;     /* time of assert event */
1954 +       struct pps_ktime clear_tu;      /* time of clear event */
1955 +       int current_mode;               /* current mode bits */
1956 +};
1957 +
1958 +struct pps_kparams {
1959 +       int api_version;                /* API version # */
1960 +       int mode;                       /* mode bits */
1961 +       struct pps_ktime assert_off_tu; /* offset compensation for assert */
1962 +       struct pps_ktime clear_off_tu;  /* offset compensation for clear */
1963 +};
1964 +
1965 +/*
1966 + * 3.3 Mode bit definitions
1967 + */
1968 +
1969 +/* Device/implementation parameters */
1970 +#define PPS_CAPTUREASSERT      0x01    /* capture assert events */
1971 +#define PPS_CAPTURECLEAR       0x02    /* capture clear events */
1972 +#define PPS_CAPTUREBOTH                0x03    /* capture assert and clear events */
1973 +
1974 +#define PPS_OFFSETASSERT       0x10    /* apply compensation for assert ev. */
1975 +#define PPS_OFFSETCLEAR                0x20    /* apply compensation for clear ev. */
1976 +
1977 +#define PPS_CANWAIT            0x100   /* can we wait for an event? */
1978 +#define PPS_CANPOLL            0x200   /* bit reserved for future use */
1979 +
1980 +/* Kernel actions */
1981 +#define PPS_ECHOASSERT         0x40    /* feed back assert event to output */
1982 +#define PPS_ECHOCLEAR          0x80    /* feed back clear event to output */
1983 +
1984 +/* Timestamp formats */
1985 +#define PPS_TSFMT_TSPEC                0x1000  /* select timespec format */
1986 +#define PPS_TSFMT_NTPFP                0x2000  /* select NTP format */
1987 +
1988 +/*
1989 + * 3.4.4 New functions: disciplining the kernel timebase
1990 + */
1991 +
1992 +/* Kernel consumers */
1993 +#define PPS_KC_HARDPPS         0       /* hardpps() (or equivalent) */
1994 +#define PPS_KC_HARDPPS_PLL     1       /* hardpps() constrained to
1995 +                                          use a phase-locked loop */
1996 +#define PPS_KC_HARDPPS_FLL     2       /* hardpps() constrained to
1997 +                                          use a frequency-locked loop */
1998 +/*
1999 + * Here begins the implementation-specific part!
2000 + */
2001 +
2002 +struct pps_fdata {
2003 +       struct pps_kinfo info;
2004 +       struct pps_ktime timeout;
2005 +};
2006 +
2007 +#include <linux/ioctl.h>
2008 +
2009 +#define PPS_CHECK              _IO('P', 0)
2010 +#define PPS_GETPARAMS          _IOR('P', 1, struct pps_kparams *)
2011 +#define PPS_SETPARAMS          _IOW('P', 2, struct pps_kparams *)
2012 +#define PPS_GETCAP             _IOR('P', 3, int *)
2013 +#define PPS_FETCH              _IOWR('P', 4, struct pps_fdata *)
2014 +
2015 +#ifdef __KERNEL__
2016 +
2017 +#include <linux/cdev.h>
2018 +#include <linux/device.h>
2019 +
2020 +#define PPS_VERSION            "5.0.0-rc2"
2021 +#define PPS_MAX_SOURCES                16              /* should be enought... */
2022 +
2023 +/*
2024 + * Global defines
2025 + */
2026 +
2027 +/* The specific PPS source info */
2028 +struct pps_source_info {
2029 +       char name[PPS_MAX_NAME_LEN];            /* simbolic name */
2030 +       char path[PPS_MAX_NAME_LEN];            /* path of connected device */
2031 +       int mode;                               /* PPS's allowed mode */
2032 +
2033 +       void (*echo)(int source, int event, void *data); /* PPS echo function */
2034 +
2035 +       struct module *owner;
2036 +       struct device *dev;
2037 +};
2038 +
2039 +/* The main struct */
2040 +struct pps_device {
2041 +       struct pps_source_info info;            /* PSS source info */
2042 +
2043 +       struct pps_kparams params;              /* PPS's current params */
2044 +
2045 +       __u32 assert_sequence;                  /* PPS' assert event seq # */
2046 +       __u32 clear_sequence;                   /* PPS' clear event seq # */
2047 +       struct pps_ktime assert_tu;
2048 +       struct pps_ktime clear_tu;
2049 +       int current_mode;                       /* PPS mode at event time */
2050 +
2051 +       int go;                                 /* PPS event is arrived? */
2052 +       wait_queue_head_t queue;                /* PPS event queue */
2053 +
2054 +       unsigned int id;                        /* PPS source unique ID */
2055 +       struct cdev cdev;
2056 +       struct device *dev;
2057 +       int devno;
2058 +       struct fasync_struct *async_queue;      /* fasync method */
2059 +       spinlock_t lock;
2060 +
2061 +       atomic_t usage;                         /* usage count */
2062 +       wait_queue_head_t usage_queue;
2063 +
2064 +       struct class_device class_dev;
2065 +};
2066 +
2067 +/*
2068 + * Exported functions
2069 + */
2070 +
2071 +extern int pps_register_source(struct pps_source_info *info,
2072 +                               int default_params);
2073 +extern void pps_unregister_source(int source);
2074 +extern int pps_register_cdev(struct pps_device *pps);
2075 +extern void pps_unregister_cdev(struct pps_device *pps);
2076 +extern void pps_event(int source, int event, void *data);
2077 +
2078 +extern int pps_sysfs_create_source_entry(struct pps_device *pps);
2079 +extern void pps_sysfs_remove_source_entry(struct pps_device *pps);
2080 +
2081 +#endif /* __KERNEL__ */
2082 +
2083 +#endif /* _PPS_H_ */
2084 --- a/include/linux/serial_core.h
2085 +++ b/include/linux/serial_core.h
2086 @@ -157,6 +157,7 @@
2087  #include <linux/tty.h>
2088  #include <linux/mutex.h>
2089  #include <linux/sysrq.h>
2090 +#include <linux/pps.h>
2091  
2092  struct uart_port;
2093  struct uart_info;
2094 @@ -236,6 +237,9 @@
2095         unsigned char           regshift;               /* reg offset shift */
2096         unsigned char           iotype;                 /* io access style */
2097         unsigned char           unused1;
2098 +#ifdef CONFIG_PPS_CLIENT_UART
2099 +       int                     pps_source;             /* PPS source ID */
2100 +#endif
2101  
2102  #define UPIO_PORT              (0)
2103  #define UPIO_HUB6              (1)
2104 @@ -280,7 +284,8 @@
2105  #define UPF_IOREMAP            ((__force upf_t) (1 << 31))
2106  
2107  #define UPF_CHANGE_MASK                ((__force upf_t) (0x17fff))
2108 -#define UPF_USR_MASK           ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
2109 +#define UPF_USR_MASK           ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY\
2110 +                                                       |UPF_HARDPPS_CD))
2111  
2112         unsigned int            mctrl;                  /* current modem ctrl settings */
2113         unsigned int            timeout;                /* character-based timeout */
2114 @@ -312,6 +317,10 @@
2115         struct uart_info        *info;
2116         struct uart_port        *port;
2117  
2118 +#ifdef CONFIG_PPS_CLIENT_UART
2119 +       struct pps_source_info  pps_info;
2120 +#endif
2121 +
2122         struct mutex            mutex;
2123  };
2124  
2125 @@ -476,13 +485,22 @@
2126  {
2127         struct uart_info *info = port->info;
2128  
2129 -       port->icount.dcd++;
2130 -
2131 -#ifdef CONFIG_HARD_PPS
2132 -       if ((port->flags & UPF_HARDPPS_CD) && status)
2133 -               hardpps();
2134 +#ifdef CONFIG_PPS_CLIENT_UART
2135 +       if (port->flags & UPF_HARDPPS_CD) {
2136 +               if (status) {
2137 +                       pps_event(port->pps_source, PPS_CAPTUREASSERT, port);
2138 +                       dev_dbg(port->dev, "PPS assert at %lu on source #%d\n",
2139 +                               jiffies, port->pps_source);
2140 +               } else {
2141 +                       pps_event(port->pps_source, PPS_CAPTURECLEAR, port);
2142 +                       dev_dbg(port->dev, "PPS clear at %lu on source #%d\n",
2143 +                               jiffies, port->pps_source);
2144 +               }
2145 +       }
2146  #endif
2147  
2148 +       port->icount.dcd++;
2149 +
2150         if (info->flags & UIF_CHECK_CD) {
2151                 if (status)
2152                         wake_up_interruptible(&info->open_wait);