[PATCH 02/10] PPS: userland header file for PPS API.

Previous thread: none

Next thread: none
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

This patch set adds the PPS support into Linux.

PPS means "pulse per second" and its API is specified by RFC 2783
(Pulse-Per-Second API for UNIX-like Operating Systems, Version 1.0).

The code has been tested with the NTPD program
(http://www.eecis.udel.edu/~mills/ntp/html/index.html) and several GPS
antennae.

Changelog

RESUBMIT 6 -> 7:

* A new line discipline has been added in order to leave untouched
  the serial ports code (as suggested by Alan).

* n_tty.c exports only GPL symbols.

* ioctl numbers fixed in order to avoid any conflicts.

* Last patch (0010-PPS-low-level-IRQ-timestamps-recording.patch) implements
  low level IRQs timestamps recording which mproves PPS precision but can
  be dropped for kernel inclusion! As suggested by Alan: "After that is
  sorted/merged we can come back to working out the best way to improve
  the IRQ and HARDPPS hacks."

Rodolfo

--

 b/Documentation/ABI/testing/sysfs-pps |   73 +++++++
 b/Documentation/ioctl-number.txt      |    2
 b/Documentation/pps/Makefile          |   28 ++
 b/Documentation/pps/pps.txt           |  172 +++++++++++++++++
 b/Documentation/pps/ppsfind           |   17 +
 b/Documentation/pps/ppsldisc.c        |   46 ++++
 b/Documentation/pps/ppstest.c         |  151 +++++++++++++++
 b/Documentation/pps/timepps.h         |  195 +++++++++++++++++++
 b/Documentation/tty.txt               |    4
 b/MAINTAINERS                         |    7
 b/arch/x86/kernel/irq_32.c            |   17 +
 b/arch/x86/kernel/irq_64.c            |   21 +-
 b/drivers/Kconfig                     |    2
 b/drivers/Makefile                    |    1
 b/drivers/char/lp.c                   |   61 ++++++
 b/drivers/char/n_tty.c                |   54 +++--
 b/drivers/pps/Kconfig                 |   33 +++
 b/drivers/pps/Makefile                |    8
 b/drivers/pps/clients/Kconfig         |   18 +
 b/drivers/pps/clients/Makefile        |    9
 b/drivers/pps/clients/ktimer.c        |  124 ++++++++++++
 ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

This patch adds the kernel side of the PPS support currently named
"LinuxPPS".

PPS means "pulse per second" and a PPS source is just a device which
provides a high precision signal each second so that an application
can use it to adjust system clock time.

Common use is the combination of the NTPD as userland program with a
GPS receiver as PPS source to obtain a wallclock-time with
sub-millisecond synchronisation to UTC.

To obtain this goal the userland programs shoud use the PPS API
specification (RFC 2783 - Pulse-Per-Second API for UNIX-like Operating
Systems, Version 1.0) which in part is implemented by this patch. It
provides a set of chars devices, one per PPS source, which can be used
to get the time signal. The RFC's functions can be implemented by
accessing to these char devices.

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 Documentation/ABI/testing/sysfs-pps |   73 ++++++++
 Documentation/ioctl-number.txt      |    2 +
 Documentation/pps/pps.txt           |  172 ++++++++++++++++++
 MAINTAINERS                         |    7 +
 drivers/Kconfig                     |    2 +
 drivers/Makefile                    |    1 +
 drivers/pps/Kconfig                 |   33 ++++
 drivers/pps/Makefile                |    8 +
 drivers/pps/kapi.c                  |  322 +++++++++++++++++++++++++++++++++
 drivers/pps/pps.c                   |  335 +++++++++++++++++++++++++++++++++++
 drivers/pps/sysfs.c                 |  104 +++++++++++
 include/linux/Kbuild                |    1 +
 include/linux/pps.h                 |  202 +++++++++++++++++++++
 13 files changed, 1262 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-pps
 create mode 100644 Documentation/pps/pps.txt
 create mode 100644 drivers/pps/Kconfig
 create mode 100644 drivers/pps/Makefile
 create mode 100644 drivers/pps/kapi.c
 create mode 100644 drivers/pps/pps.c
 create mode 100644 drivers/pps/sysfs.c
 create mode 100644 include/linux/pps.h

diff --git ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

This patch adds into the PPS's documentation directory a possible
implementation of the PPS API (RFC 2783) by using the LinuxPPS's char
devices.

This file is not just an example but it can be used into real
systems. :)

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 Documentation/pps/timepps.h |  195 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 195 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/pps/timepps.h

diff --git a/Documentation/pps/timepps.h b/Documentation/pps/timepps.h
new file mode 100644
index 0000000..2372949
--- /dev/null
+++ b/Documentation/pps/timepps.h
@@ -0,0 +1,195 @@
+/*
+ * timepps.h -- PPS API main header
+ *
+ * Copyright (C) 2005-2007   Rodolfo Giometti <giometti@linux.it>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _SYS_TIMEPPS_H_
+#define _SYS_TIMEPPS_H_
+
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <errno.h>
+#include <linux/pps.h>
+
+#define LINUXPPS	1		/* signal we are using LinuxPPS */
+
+/*
+ * New data structures
+ */
+
+struct ntp_fp {
+	unsigned int integral;
+	unsigned int fractional;
+};
+
+union pps_timeu {
+	struct timespec tspec;
+	struct ntp_fp ntpfp;
+	unsigned long longpad[3];
+};
+
+struct pps_info {
+	unsigned long assert_sequence;	/* seq. num. of ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Here some utilities and examples about the PPS API and the LinuxPPS
support.

* ppsldisc.c shows how to manage PPS line discipline;

* ppstest.c implements an useful testing program, while

* ppsfind tries to help the user into finding a specific PPS source by
  using its name or path.

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 Documentation/pps/Makefile   |   28 ++++++++
 Documentation/pps/ppsfind    |   17 +++++
 Documentation/pps/ppsldisc.c |   46 +++++++++++++
 Documentation/pps/ppstest.c  |  151 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 242 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/pps/Makefile
 create mode 100644 Documentation/pps/ppsfind
 create mode 100644 Documentation/pps/ppsldisc.c
 create mode 100644 Documentation/pps/ppstest.c

diff --git a/Documentation/pps/Makefile b/Documentation/pps/Makefile
new file mode 100644
index 0000000..9841e6b
--- /dev/null
+++ b/Documentation/pps/Makefile
@@ -0,0 +1,28 @@
+TARGETS = ppstest ppsldisc
+
+CFLAGS += -Wall -O2 -D_GNU_SOURCE
+CFLAGS += -I .
+CFLAGS += -ggdb
+CFLAGS += -D__N_PPS=$(shell awk '/N_PPS/ {print $$3}' ../../include/linux/tty.h)
+
+# -- Actions section --
+
+.PHONY : all depend dep
+
+all : .depend $(TARGETS)
+
+.depend depend dep :
+	$(CC) $(CFLAGS) -M $(TARGETS:=.c) > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+
+# -- Clean section --
+
+.PHONY : clean
+
+clean :
+	rm -f *.o *~ core .depend
+	rm -f ${TARGETS}
diff --git a/Documentation/pps/ppsfind b/Documentation/pps/ppsfind
new file mode 100644
index 0000000..93c0e17
--- /dev/null
+++ b/Documentation/pps/ppsfind
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+SYS="/sys/class/pps/"
+
+if [ $# -lt 1 ] ; then
+	echo "usage: ppsfind <name>" >&2
+	exit 1
+fi
+
+for d in $(ls $SYS) ; do
+	if grep $1 $SYS/$d/name >& /dev/null || \
+	   grep $1 $SYS/$d/path >& /dev/null ; then
+		echo "$d: name=$(cat $SYS/$d/name) path=$(cat $SYS/$d/path)"
+	fi
+done
+
+exit ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Each PPS source can be registered/deregistered into the system by
using special modules called "clients". They simply define the PPS
sources' attributes and implement the time signal registartion
mechanism.

This patch adds a special directory for such clients and adds a dummy
client that can be useful to test system integrity on real systems.

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 drivers/pps/Kconfig          |    2 +
 drivers/pps/Makefile         |    1 +
 drivers/pps/clients/Kconfig  |   18 ++++++
 drivers/pps/clients/Makefile |    9 +++
 drivers/pps/clients/ktimer.c |  124 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 154 insertions(+), 0 deletions(-)
 create mode 100644 drivers/pps/clients/Kconfig
 create mode 100644 drivers/pps/clients/Makefile
 create mode 100644 drivers/pps/clients/ktimer.c

diff --git a/drivers/pps/Kconfig b/drivers/pps/Kconfig
index cc2eb8e..1afe4e0 100644
--- a/drivers/pps/Kconfig
+++ b/drivers/pps/Kconfig
@@ -30,4 +30,6 @@ config PPS_DEBUG
 	  messages to the system log.  Select this if you are having a
 	  problem with PPS support and want to see more of what is going on.
 
+source drivers/pps/clients/Kconfig
+
 endmenu
diff --git a/drivers/pps/Makefile b/drivers/pps/Makefile
index 19ea582..98960dd 100644
--- a/drivers/pps/Makefile
+++ b/drivers/pps/Makefile
@@ -4,5 +4,6 @@
 
 pps_core-y			:= pps.o kapi.o sysfs.o
 obj-$(CONFIG_PPS)		:= pps_core.o
+obj-y				+= clients/
 
 ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig
new file mode 100644
index 0000000..60b83be
--- /dev/null
+++ b/drivers/pps/clients/Kconfig
@@ -0,0 +1,18 @@
+#
+# PPS clients configuration
+#
+
+if PPS
+
+comment "PPS clients support"
+
+config PPS_CLIENT_KTIMER
+	tristate "Kernel timer client (Testing client, use for debug)"
+	help
+	  If you say yes here you get support for a PPS debugging client
+	  which uses a kernel timer to generate the PPS ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 Documentation/tty.txt     |    4 ++++
 include/linux/tty_ldisc.h |    8 ++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/Documentation/tty.txt b/Documentation/tty.txt
index 8e65c44..3fc812a 100644
--- a/Documentation/tty.txt
+++ b/Documentation/tty.txt
@@ -100,6 +100,10 @@ write_wakeup()	-	May be called at any point between open and close.
 			is permitted to call the driver write method from
 			this function. In such a situation defer it.
 
+dcd_change()	-	Report to the tty line the current DCD pin status
+			changes and the relative timestamp. The timestamp
+			can be NULL.
+
 
 Driver Access
 
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index 40f38d8..526fbf4 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -99,6 +99,12 @@
  *	cease I/O to the tty driver. Can sleep. The driver should
  *	seek to perform this action quickly but should wait until
  *	any pending driver I/O is completed.
+ *
+ * void (*dcd_change)(struct tty_struct *tty, unsigned int status,
+ * 			struct timespec *ts)
+ *
+ *	Tells the discipline that the DCD pin has changed its status and
+ *	the relative timestamp. Pointer ts can be NULL.
  */
 
 #include <linux/fs.h>
@@ -136,6 +142,8 @@ struct tty_ldisc_ops {
 	void	(*receive_buf)(struct tty_struct *, const unsigned char *cp,
 			       char *fp, int count);
 	void	(*write_wakeup)(struct tty_struct *);
+	void	(*dcd_change)(struct tty_struct *, unsigned int,
+				struct timespec *);
 
 	struct  module *owner;
 	
-- 
1.5.4.3

--

From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 drivers/char/n_tty.c |   54 +++++++++++++++++++++++++++++--------------------
 include/linux/tty.h  |   16 ++++++++++++++
 2 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 708c2b1..8458ded 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -26,7 +26,7 @@
  *
  * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
  *		waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
- *		Also fixed a bug in BLOCKING mode where write_chan returns
+ *		Also fixed a bug in BLOCKING mode where n_tty_write returns
  *		EAGAIN
  */
 
@@ -43,10 +43,10 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/bitops.h>
 #include <linux/audit.h>
 #include <linux/file.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -184,7 +184,7 @@ static void reset_buffer_flags(struct tty_struct *tty)
  *	Locking: ctrl_lock
  */
 
-static void n_tty_flush_buffer(struct tty_struct *tty)
+void n_tty_flush_buffer(struct tty_struct *tty)
 {
 	unsigned long flags;
 	/* clear everything and unthrottle the driver */
@@ -200,6 +200,7 @@ static void n_tty_flush_buffer(struct tty_struct *tty)
 	}
 	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 }
+EXPORT_SYMBOL_GPL(n_tty_flush_buffer);
 
 /**
  *	n_tty_chars_in_buffer	-	report available bytes
@@ -209,7 +210,7 @@ static void n_tty_flush_buffer(struct tty_struct *tty)
  *	at this instant in time.
  */
 
-static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
+ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
 {
 	unsigned long flags;
 	ssize_t n = 0;
@@ -225,6 +226,7 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
 	spin_unlock_irqrestore(&tty->read_lock, flags);
 	return n;
 }
+EXPORT_SYMBOL_GPL(n_tty_chars_in_buffer);
 
 /**
  *	is_utf8_continuation	-	utf8 ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Add a new line discipline for "pulse per second" devices connected to
a serial port.

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 include/linux/tty.h |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/include/linux/tty.h b/include/linux/tty.h
index 826d695..1857db2 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -24,7 +24,7 @@
  */
 #define NR_UNIX98_PTY_DEFAULT	4096      /* Default maximum for Unix98 ptys */
 #define NR_UNIX98_PTY_MAX	(1 << MINORBITS) /* Absolute limit */
-#define NR_LDISCS		18
+#define NR_LDISCS		19
 
 /* line disciplines */
 #define N_TTY		0
@@ -46,6 +46,7 @@
 #define N_HCI		15	/* Bluetooth HCI UART */
 #define N_GIGASET_M101	16	/* Siemens Gigaset M101 serial DECT adapter */
 #define N_SLCAN		17	/* Serial / USB serial CAN Adaptors */
+#define N_PPS		18	/* Pulse per Second */
 
 /*
  * This character is the same as _POSIX_VDISABLE: it cannot be used as
-- 
1.5.4.3

--

From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Adds support, by using the PPS line discipline, for the PPS sources
connected with the CD (Carrier Detect) pin of a serial port.

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 drivers/pps/clients/Kconfig     |    7 ++
 drivers/pps/clients/Makefile    |    1 +
 drivers/pps/clients/pps-ldisc.c |  154 +++++++++++++++++++++++++++++++++++++++
 drivers/serial/8250.c           |   13 +++
 include/linux/serial_core.h     |   10 ++-
 5 files changed, 184 insertions(+), 1 deletions(-)
 create mode 100644 drivers/pps/clients/pps-ldisc.c

diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig
index 60b83be..487c1c8 100644
--- a/drivers/pps/clients/Kconfig
+++ b/drivers/pps/clients/Kconfig
@@ -15,4 +15,11 @@ config PPS_CLIENT_KTIMER
 	  This driver can also be built as a module.  If so, the module
 	  will be called ktimer.ko.
 
+config PPS_CLIENT_LDISC
+	tristate "PPS line discipline"
+	depends on PPS
+	help
+	  If you say yes here you get support for a PPS source connected
+	  with the CD (Carrier Detect) pin of your serial port.
+
 endif
diff --git a/drivers/pps/clients/Makefile b/drivers/pps/clients/Makefile
index f3c1e39..9f5b988 100644
--- a/drivers/pps/clients/Makefile
+++ b/drivers/pps/clients/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_PPS_CLIENT_KTIMER)	+= ktimer.o
+obj-$(CONFIG_PPS_CLIENT_LDISC)	+= pps-ldisc.o
 
 ifeq ($(CONFIG_PPS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c
new file mode 100644
index 0000000..6484f17
--- /dev/null
+++ b/drivers/pps/clients/pps-ldisc.c
@@ -0,0 +1,154 @@
+/*
+ * pps-ldisc.c -- PPS line discipline
+ *
+ *
+ * Copyright (C) 2008	Rodolfo Giometti <giometti@linux.it>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Adds support for the PPS sources connected with the interrupt pin of a
parallel port.

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 drivers/char/lp.c           |   61 +++++++++++++++++++++++++++++++++++++++++++
 drivers/pps/clients/Kconfig |   10 +++++++
 include/linux/parport.h     |   22 +++++++++++++++
 3 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 3f2719b..84e0bb0 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -760,6 +760,27 @@ static struct console lpcons = {
 
 #endif /* console on line printer */
 
+/* Support for PPS signal on the line printer */
+
+#ifdef CONFIG_PPS_CLIENT_LP
+
+static void lp_pps_echo(int source, int event, void *data)
+{
+	struct parport *port = data;
+	unsigned char status = parport_read_status(port);
+
+	/* echo event via SEL bit */
+	parport_write_control(port,
+		parport_read_control(port) | PARPORT_CONTROL_SELECT);
+
+	/* signal no event */
+	if ((status & PARPORT_STATUS_ACK) != 0)
+		parport_write_control(port,
+			parport_read_control(port) & ~PARPORT_CONTROL_SELECT);
+}
+
+#endif
+
 /* --- initialisation code ------------------------------------- */
 
 static int parport_nr[LP_NO] = { [0 ... LP_NO-1] = LP_PARPORT_UNSPEC };
@@ -831,6 +852,38 @@ static int lp_register(int nr, struct parport *port)
 	}
 #endif
 
+#ifdef CONFIG_PPS_CLIENT_LP
+	port->pps_info.owner = THIS_MODULE;
+	port->pps_info.dev = port->dev;
+	snprintf(port->pps_info.path, PPS_MAX_NAME_LEN, "/dev/lp%d", nr);
+
+	/* No PPS support if lp port has no IRQ line */
+	if (port->irq != PARPORT_IRQ_NONE) {
+		strncpy(port->pps_info.name, port->name, PPS_MAX_NAME_LEN);
+
+		port->pps_info.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \
+				PPS_ECHOASSERT | \
+				PPS_CANWAIT | PPS_TSFMT_TSPEC;
+
+		port->pps_info.echo = lp_pps_echo;
+
+		port->pps_source = pps_register_source(&(port->pps_info),
+				PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
+		if (port->pps_source < ...
From: Rodolfo Giometti
Date: Wednesday, September 10, 2008 - 12:52 am

Add low level IRQ timestamps recording for x86 (32 and 64 bits)
platforms and enable UART clients in order to use it.

This improves PPS precision. :)

Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
 arch/x86/kernel/irq_32.c    |   17 +++++++++++++++++
 arch/x86/kernel/irq_64.c    |   21 +++++++++++++++++++--
 drivers/pps/Kconfig         |   12 ++++++++++++
 include/linux/pps.h         |    1 +
 include/linux/serial_core.h |    7 ++++++-
 5 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 1cf8c1f..85c3182 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -15,6 +15,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
+#include <linux/pps.h>
 
 #include <asm/apic.h>
 #include <asm/uaccess.h>
@@ -25,6 +26,11 @@ EXPORT_PER_CPU_SYMBOL(irq_stat);
 DEFINE_PER_CPU(struct pt_regs *, irq_regs);
 EXPORT_PER_CPU_SYMBOL(irq_regs);
 
+#ifdef CONFIG_PPS_IRQ_EVENTS
+struct timespec pps_irq_ts[NR_IRQS];
+EXPORT_SYMBOL(pps_irq_ts);
+#endif
+
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
@@ -225,6 +231,12 @@ unsigned int do_IRQ(struct pt_regs *regs)
 	/* high bit used in ret_from_ code */
 	int overflow, irq = ~regs->orig_ax;
 	struct irq_desc *desc = irq_desc + irq;
+#ifdef CONFIG_PPS_IRQ_EVENTS
+	struct timespec ts;
+
+	/* Get IRQ timestamps as soon as possible for the PPS layer */
+	getnstimeofday(&ts);
+#endif
 
 	if (unlikely((unsigned)irq >= NR_IRQS)) {
 		printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
@@ -232,6 +244,11 @@ unsigned int do_IRQ(struct pt_regs *regs)
 		BUG();
 	}
 
+#ifdef CONFIG_PPS_IRQ_EVENTS
+	/* Then, after sanity check, store the IRQ timestamp */
+	pps_irq_ts[irq] = ts;
+#endif
+
 	old_regs = set_irq_regs(regs);
 	irq_enter();
 
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 1f78b23..e9184ce 100644
--- ...
Previous thread: none

Next thread: none