* LinuxPPS new functionalities
@ 2010-02-16 9:51 Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 1/8] pps: userland header file for PPS API Rodolfo Giometti
2010-02-16 12:28 ` LinuxPPS new functionalities Alan Cox
0 siblings, 2 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev
This patchset adds several PPS functionalities.
All patches have a specific comment but I prefer say something more:
* Patches 01-02 are just documentation about PPS support.
* Patch 03 adds PPS client support skeleton.
* Patches 04-06 add generic PPS serial support (with specific
modifications requested by Alan Cox).
* Patches 07-08 add PPS serial support for specific hardware.
Ciao,
Rodolfo
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/8] pps: userland header file for PPS API.
2010-02-16 9:51 LinuxPPS new functionalities Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 2/8] pps: documentation programs and examples Rodolfo Giometti
2010-02-16 12:33 ` [PATCH 1/8] pps: userland header file for PPS API Alexander Gordeev
2010-02-16 12:28 ` LinuxPPS new functionalities Alan Cox
1 sibling, 2 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
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 | 198 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 198 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..d2628d2
--- /dev/null
+++ b/Documentation/pps/timepps.h
@@ -0,0 +1,198 @@
+/*
+ * 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 <errno.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <linux/types.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 assert event */
+ unsigned long clear_sequence; /* seq. num. of clear event */
+ union pps_timeu assert_tu; /* time of assert event */
+ union pps_timeu clear_tu; /* time of clear event */
+ int current_mode; /* current mode bits */
+};
+
+struct pps_params {
+ int api_version; /* API version # */
+ int mode; /* mode bits */
+ union pps_timeu assert_off_tu; /* offset compensation for assert */
+ union pps_timeu clear_off_tu; /* offset compensation for clear */
+};
+
+typedef int pps_handle_t; /* represents a PPS source */
+typedef unsigned long pps_seq_t; /* sequence number */
+typedef struct ntp_fp ntp_fp_t; /* NTP-compatible time stamp */
+typedef union pps_timeu pps_timeu_t; /* generic data type for time stamps */
+typedef struct pps_info pps_info_t;
+typedef struct pps_params pps_params_t;
+
+#define assert_timestamp assert_tu.tspec
+#define clear_timestamp clear_tu.tspec
+
+#define assert_timestamp_ntpfp assert_tu.ntpfp
+#define clear_timestamp_ntpfp clear_tu.ntpfp
+
+#define assert_offset assert_off_tu.tspec
+#define clear_offset clear_off_tu.tspec
+
+#define assert_offset_ntpfp assert_off_tu.ntpfp
+#define clear_offset_ntpfp clear_off_tu.ntpfp
+
+/*
+ * The PPS API
+ */
+
+static __inline int time_pps_create(int source, pps_handle_t *handle)
+{
+ int ret;
+ struct pps_kparams dummy;
+
+ if (!handle) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* First we check if current device is a valid PPS one by
+ * doing a dummy PPS_GETPARAMS...
+ */
+ ret = ioctl(source, PPS_GETPARAMS, &dummy);
+ if (ret) {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+
+ /* ... then since in LinuxPPS there are no differences between a
+ * "PPS source" and a "PPS handle", we simply return the same value.
+ */
+ *handle = source;
+
+ return 0;
+}
+
+static __inline int time_pps_destroy(pps_handle_t handle)
+{
+ return close(handle);
+}
+
+static __inline int time_pps_getparams(pps_handle_t handle,
+ pps_params_t *ppsparams)
+{
+ int ret;
+ struct pps_kparams __ppsparams;
+
+ ret = ioctl(handle, PPS_GETPARAMS, &__ppsparams);
+
+ ppsparams->api_version = __ppsparams.api_version;
+ ppsparams->mode = __ppsparams.mode;
+ ppsparams->assert_off_tu.tspec.tv_sec = __ppsparams.assert_off_tu.sec;
+ ppsparams->assert_off_tu.tspec.tv_nsec = __ppsparams.assert_off_tu.nsec;
+ ppsparams->clear_off_tu.tspec.tv_sec = __ppsparams.clear_off_tu.sec;
+ ppsparams->clear_off_tu.tspec.tv_nsec = __ppsparams.clear_off_tu.nsec;
+
+ return ret;
+}
+
+static __inline int time_pps_setparams(pps_handle_t handle,
+ const pps_params_t *ppsparams)
+{
+ struct pps_kparams __ppsparams;
+
+ __ppsparams.api_version = ppsparams->api_version;
+ __ppsparams.mode = ppsparams->mode;
+ __ppsparams.assert_off_tu.sec = ppsparams->assert_off_tu.tspec.tv_sec;
+ __ppsparams.assert_off_tu.nsec = ppsparams->assert_off_tu.tspec.tv_nsec;
+ __ppsparams.clear_off_tu.sec = ppsparams->clear_off_tu.tspec.tv_sec;
+ __ppsparams.clear_off_tu.nsec = ppsparams->clear_off_tu.tspec.tv_nsec;
+
+ return ioctl(handle, PPS_SETPARAMS, &__ppsparams);
+}
+
+/* Get capabilities for handle */
+static __inline int time_pps_getcap(pps_handle_t handle, int *mode)
+{
+ return ioctl(handle, PPS_GETCAP, mode);
+}
+
+static __inline int time_pps_fetch(pps_handle_t handle, const int tsformat,
+ pps_info_t *ppsinfobuf,
+ const struct timespec *timeout)
+{
+ struct pps_fdata __fdata;
+ int ret;
+
+ /* Sanity checks */
+ if (tsformat != PPS_TSFMT_TSPEC) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (timeout) {
+ __fdata.timeout.sec = timeout->tv_sec;
+ __fdata.timeout.nsec = timeout->tv_nsec;
+ __fdata.timeout.flags = ~PPS_TIME_INVALID;
+ } else
+ __fdata.timeout.flags = PPS_TIME_INVALID;
+
+ ret = ioctl(handle, PPS_FETCH, &__fdata);
+
+ ppsinfobuf->assert_sequence = __fdata.info.assert_sequence;
+ ppsinfobuf->clear_sequence = __fdata.info.clear_sequence;
+ ppsinfobuf->assert_tu.tspec.tv_sec = __fdata.info.assert_tu.sec;
+ ppsinfobuf->assert_tu.tspec.tv_nsec = __fdata.info.assert_tu.nsec;
+ ppsinfobuf->clear_tu.tspec.tv_sec = __fdata.info.clear_tu.sec;
+ ppsinfobuf->clear_tu.tspec.tv_nsec = __fdata.info.clear_tu.nsec;
+ ppsinfobuf->current_mode = __fdata.info.current_mode;
+
+ return ret;
+}
+
+static __inline int time_pps_kcbind(pps_handle_t handle,
+ const int kernel_consumer,
+ const int edge, const int tsformat)
+{
+ /* LinuxPPS doesn't implement kernel consumer feature */
+ errno = EOPNOTSUPP;
+ return -1;
+}
+
+#endif /* _SYS_TIMEPPS_H_ */
--
1.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/8] pps: documentation programs and examples.
2010-02-16 9:51 ` [PATCH 1/8] pps: userland header file for PPS API Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 3/8] pps: LinuxPPS clients support Rodolfo Giometti
2010-02-16 12:44 ` [PATCH 2/8] pps: documentation programs and examples Alexander Gordeev
2010-02-16 12:33 ` [PATCH 1/8] pps: userland header file for PPS API Alexander Gordeev
1 sibling, 2 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
Here some utilities and examples about the PPS API and the LinuxPPS
support.
* 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 | 27 ++++++++
Documentation/pps/ppsfind | 17 +++++
Documentation/pps/ppstest.c | 150 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 194 insertions(+), 0 deletions(-)
create mode 100644 Documentation/pps/Makefile
create mode 100644 Documentation/pps/ppsfind
create mode 100644 Documentation/pps/ppstest.c
diff --git a/Documentation/pps/Makefile b/Documentation/pps/Makefile
new file mode 100644
index 0000000..3848aba
--- /dev/null
+++ b/Documentation/pps/Makefile
@@ -0,0 +1,27 @@
+TARGETS = ppstest
+
+CFLAGS += -Wall -O2 -D_GNU_SOURCE
+CFLAGS += -I . -I ../../include/
+CFLAGS += -ggdb
+
+# -- 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 0
diff --git a/Documentation/pps/ppstest.c b/Documentation/pps/ppstest.c
new file mode 100644
index 0000000..30c8f6d
--- /dev/null
+++ b/Documentation/pps/ppstest.c
@@ -0,0 +1,150 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <timepps.h>
+
+int find_source(char *path, pps_handle_t *handle, int *avail_mode)
+{
+ pps_params_t params;
+ int ret;
+
+ printf("trying PPS source \"%s\"\n", path);
+
+ /* Try to find the source by using the supplied "path" name */
+ ret = open(path, O_RDWR);
+ if (ret < 0) {
+ fprintf(stderr, "unable to open device \"%s\" (%m)\n", path);
+ return ret;
+ }
+
+ /* Open the PPS source (and check the file descriptor) */
+ ret = time_pps_create(ret, handle);
+ if (ret < 0) {
+ fprintf(stderr, "cannot create a PPS source from device "
+ "\"%s\" (%m)\n", path);
+ return -1;
+ }
+ printf("found PPS source \"%s\"\n", path);
+
+ /* Find out what features are supported */
+ ret = time_pps_getcap(*handle, avail_mode);
+ if (ret < 0) {
+ fprintf(stderr, "cannot get capabilities (%m)\n");
+ return -1;
+ }
+ if ((*avail_mode & PPS_CAPTUREASSERT) == 0) {
+ fprintf(stderr, "cannot CAPTUREASSERT\n");
+ return -1;
+ }
+ if ((*avail_mode & PPS_OFFSETASSERT) == 0) {
+ fprintf(stderr, "cannot OFFSETASSERT\n");
+ return -1;
+ }
+
+ /* Capture assert timestamps, and compensate for a 675 nsec
+ * propagation delay */
+ ret = time_pps_getparams(*handle, ¶ms);
+ if (ret < 0) {
+ fprintf(stderr, "cannot get parameters (%m)\n");
+ return -1;
+ }
+ params.assert_offset.tv_sec = 0;
+ params.assert_offset.tv_nsec = 675;
+ params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
+ params.mode &= ~(PPS_CAPTURECLEAR | PPS_OFFSETCLEAR);
+ ret = time_pps_setparams(*handle, ¶ms);
+ if (ret < 0) {
+ fprintf(stderr, "cannot set parameters (%m)\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int fetch_source(int i, pps_handle_t *handle, int *avail_mode)
+{
+ struct timespec timeout;
+ pps_info_t infobuf;
+ int ret;
+
+ /* create a zero-valued timeout */
+ timeout.tv_sec = 3;
+ timeout.tv_nsec = 0;
+
+retry:
+ if (*avail_mode & PPS_CANWAIT) /* waits for the next event */
+ ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,
+ &timeout);
+ else {
+ sleep(1);
+ ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,
+ &timeout);
+ }
+ if (ret < 0) {
+ if (ret == -EINTR) {
+ fprintf(stderr, "time_pps_fetch() got a signal!\n");
+ goto retry;
+ }
+
+ fprintf(stderr, "time_pps_fetch() error %d (%m)\n", ret);
+ return -1;
+ }
+
+ printf("source %d - "
+ "assert %ld.%09ld, sequence: %ld - "
+ "clear %ld.%09ld, sequence: %ld\n",
+ i,
+ infobuf.assert_timestamp.tv_sec,
+ infobuf.assert_timestamp.tv_nsec,
+ infobuf.assert_sequence,
+ infobuf.clear_timestamp.tv_sec,
+ infobuf.clear_timestamp.tv_nsec, infobuf.clear_sequence);
+
+ return 0;
+}
+
+void usage(char *name)
+{
+ fprintf(stderr, "usage: %s <ppsdev> [<ppsdev> ...]\n", name);
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char *argv[])
+{
+ int num;
+ pps_handle_t handle[4];
+ int avail_mode[4];
+ int i = 0;
+ int ret;
+
+ /* Check the command line */
+ if (argc < 2)
+ usage(argv[0]);
+
+ for (i = 1; i < argc && i <= 4; i++) {
+ ret = find_source(argv[i], &handle[i - 1], &avail_mode[i - 1]);
+ if (ret < 0)
+ exit(EXIT_FAILURE);
+ }
+
+ num = i - 1;
+ printf("ok, found %d source(s), now start fetching data...\n", num);
+
+ /* loop, printing the most recent timestamp every second or so */
+ while (1) {
+ for (i = 0; i < num; i++) {
+ ret = fetch_source(i, &handle[i], &avail_mode[i]);
+ if (ret < 0 && errno != ETIMEDOUT)
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ for (; i >= 0; i--)
+ time_pps_destroy(handle[i]);
+
+ return 0;
+}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/8] pps: LinuxPPS clients support.
2010-02-16 9:51 ` [PATCH 2/8] pps: documentation programs and examples Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 4/8] ldisc: new dcd_change() method for line disciplines Rodolfo Giometti
2010-02-16 12:44 ` [PATCH 2/8] pps: documentation programs and examples Alexander Gordeev
1 sibling, 1 reply; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
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 | 123 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 153 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 signal.
+
+ This driver can also be built as a module. If so, the module
+ will be called ktimer.ko.
+
+endif
diff --git a/drivers/pps/clients/Makefile b/drivers/pps/clients/Makefile
new file mode 100644
index 0000000..f3c1e39
--- /dev/null
+++ b/drivers/pps/clients/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for PPS clients.
+#
+
+obj-$(CONFIG_PPS_CLIENT_KTIMER) += ktimer.o
+
+ifeq ($(CONFIG_PPS_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/pps/clients/ktimer.c b/drivers/pps/clients/ktimer.c
new file mode 100644
index 0000000..6de5dfc
--- /dev/null
+++ b/drivers/pps/clients/ktimer.c
@@ -0,0 +1,123 @@
+/*
+ * ktimer.c -- kernel timer test client
+ *
+ *
+ * Copyright (C) 2005-2006 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.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/pps_kernel.h>
+
+/*
+ * Global variables
+ */
+
+static int source;
+static struct timer_list ktimer;
+
+/*
+ * The kernel timer
+ */
+
+static void pps_ktimer_event(unsigned long ptr)
+{
+ struct timespec __ts;
+ struct pps_ktime ts;
+
+ /* First of all we get the time stamp... */
+ getnstimeofday(&__ts);
+
+ pr_info("PPS event at %lu\n", jiffies);
+
+ /* ... and translate it to PPS time data struct */
+ ts.sec = __ts.tv_sec;
+ ts.nsec = __ts.tv_nsec;
+
+ pps_event(source, &ts, PPS_CAPTUREASSERT, NULL);
+
+ mod_timer(&ktimer, jiffies + HZ);
+}
+
+/*
+ * The echo function
+ */
+
+static void pps_ktimer_echo(int source, int event, void *data)
+{
+ pr_info("echo %s %s for source %d\n",
+ event & PPS_CAPTUREASSERT ? "assert" : "",
+ event & PPS_CAPTURECLEAR ? "clear" : "",
+ source);
+}
+
+/*
+ * The PPS info struct
+ */
+
+static struct pps_source_info pps_ktimer_info = {
+ .name = "ktimer",
+ .path = "",
+ .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \
+ PPS_ECHOASSERT | \
+ PPS_CANWAIT | PPS_TSFMT_TSPEC,
+ .echo = pps_ktimer_echo,
+ .owner = THIS_MODULE,
+};
+
+/*
+ * Module staff
+ */
+
+static void __exit pps_ktimer_exit(void)
+{
+ del_timer_sync(&ktimer);
+ pps_unregister_source(source);
+
+ pr_info("ktimer PPS source unregistered\n");
+}
+
+static int __init pps_ktimer_init(void)
+{
+ int ret;
+
+ ret = pps_register_source(&pps_ktimer_info,
+ PPS_CAPTUREASSERT | PPS_OFFSETASSERT);
+ if (ret < 0) {
+ printk(KERN_ERR "cannot register ktimer source\n");
+ return ret;
+ }
+ source = ret;
+
+ setup_timer(&ktimer, pps_ktimer_event, 0);
+ mod_timer(&ktimer, jiffies + HZ);
+
+ pr_info("ktimer PPS source registered at %d\n", source);
+
+ return 0;
+}
+
+module_init(pps_ktimer_init);
+module_exit(pps_ktimer_exit);
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("dummy PPS source by using a kernel timer (just for debug)");
+MODULE_LICENSE("GPL");
--
1.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/8] ldisc: new dcd_change() method for line disciplines.
2010-02-16 9:51 ` [PATCH 3/8] pps: LinuxPPS clients support Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops() Rodolfo Giometti
0 siblings, 1 reply; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
Documentation/serial/tty.txt | 4 ++++
include/linux/tty_ldisc.h | 8 ++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt
index 8e65c44..3fc812a 100644
--- a/Documentation/serial/tty.txt
+++ b/Documentation/serial/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 0c4ee9b..526d66f 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.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops()
2010-02-16 9:51 ` [PATCH 4/8] ldisc: new dcd_change() method for line disciplines Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 6/8] pps: serial clients support Rodolfo Giometti
2010-02-19 21:45 ` [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops() Andrew Morton
0 siblings, 2 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
This new method can be used to init a new struct tty_ldisc_ops as the
default tty_ldisc_N_TTY struct.
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
drivers/char/n_tty.c | 9 +++++++++
include/linux/tty.h | 1 +
2 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 2e50f4d..0f11375 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -48,6 +48,7 @@
#include <linux/audit.h>
#include <linux/file.h>
#include <linux/uaccess.h>
+#include <linux/module.h>
#include <asm/system.h>
@@ -2091,3 +2092,11 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = {
.receive_buf = n_tty_receive_buf,
.write_wakeup = n_tty_write_wakeup
};
+
+void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
+{
+ *ops = tty_ldisc_N_TTY;
+ ops->owner = NULL;
+ ops->refcount = ops->flags = 0;
+}
+EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f0f43d0..5091438 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -485,6 +485,7 @@ extern void tty_ldisc_enable(struct tty_struct *tty);
/* n_tty.c */
extern struct tty_ldisc_ops tty_ldisc_N_TTY;
+extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops);
/* tty_audit.c */
#ifdef CONFIG_AUDIT
--
1.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 6/8] pps: serial clients support.
2010-02-16 9:51 ` [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops() Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 7/8] serial 8250: enable PPS support Rodolfo Giometti
2010-02-19 21:53 ` [PATCH 6/8] pps: serial clients support Andrew Morton
2010-02-19 21:45 ` [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops() Andrew Morton
1 sibling, 2 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
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 +++++++++++++++++++++++++++++++++++++++
include/linux/serial_core.h | 11 +++-
4 files changed, 172 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..59e6301
--- /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.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/pps_kernel.h>
+
+#define PPS_TTY_MAGIC 0x0001
+
+static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status,
+ struct timespec *ts)
+{
+ int id = (int) tty->disc_data;
+ struct timespec __ts;
+ struct pps_ktime pps_ts;
+
+ /* First of all we get the time stamp... */
+ getnstimeofday(&__ts);
+
+ /* Does caller give us a timestamp? */
+ if (ts) { /* Yes. Let's use it! */
+ pps_ts.sec = ts->tv_sec;
+ pps_ts.nsec = ts->tv_nsec;
+ } else { /* No. Do it ourself! */
+ pps_ts.sec = __ts.tv_sec;
+ pps_ts.nsec = __ts.tv_nsec;
+ }
+
+ /* Now do the PPS event report */
+ pps_event(id, &pps_ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR,
+ NULL);
+
+ pr_debug("PPS %s at %lu on source #%d\n",
+ status ? "assert" : "clear", jiffies, id);
+}
+
+static int (*n_tty_open)(struct tty_struct *tty);
+
+static int pps_tty_open(struct tty_struct *tty)
+{
+ struct pps_source_info info;
+ struct tty_driver *drv = tty->driver;
+ int index = tty->index + drv->name_base;
+ int ret;
+
+ info.owner = THIS_MODULE;
+ info.dev = NULL;
+ snprintf(info.name, PPS_MAX_NAME_LEN, "%s%d", drv->driver_name, index);
+ snprintf(info.path, PPS_MAX_NAME_LEN, "/dev/%s%d", drv->name, index);
+ info.mode = PPS_CAPTUREBOTH | \
+ PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
+ PPS_CANWAIT | PPS_TSFMT_TSPEC;
+
+ ret = pps_register_source(&info, PPS_CAPTUREBOTH | \
+ PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
+ if (ret < 0) {
+ pr_err("cannot register PPS source \"%s\"\n", info.path);
+ return ret;
+ }
+ tty->disc_data = (void *) ret;
+
+ /* Should open N_TTY ldisc too */
+ ret = n_tty_open(tty);
+ if (ret < 0)
+ pps_unregister_source((int) tty->disc_data);
+
+ pr_info("PPS source #%d \"%s\" added\n", ret, info.path);
+
+ return 0;
+}
+
+static void (*n_tty_close)(struct tty_struct *tty);
+
+static void pps_tty_close(struct tty_struct *tty)
+{
+ int id = (int) tty->disc_data;
+
+ pps_unregister_source(id);
+ n_tty_close(tty);
+
+ pr_info("PPS source #%d removed\n", id);
+}
+
+static struct tty_ldisc_ops pps_ldisc_ops;
+
+/*
+ * Module stuff
+ */
+
+static int __init pps_tty_init(void)
+{
+ int err;
+
+ /* Inherit the N_TTY's ops */
+ n_tty_inherit_ops(&pps_ldisc_ops);
+
+ /* Save N_TTY's open()/close() methods */
+ n_tty_open = pps_ldisc_ops.open;
+ n_tty_close = pps_ldisc_ops.close;
+
+ /* Init PPS_TTY data */
+ pps_ldisc_ops.owner = THIS_MODULE;
+ pps_ldisc_ops.magic = PPS_TTY_MAGIC;
+ pps_ldisc_ops.name = "pps_tty";
+ pps_ldisc_ops.dcd_change = pps_tty_dcd_change;
+ pps_ldisc_ops.open = pps_tty_open;
+ pps_ldisc_ops.close = pps_tty_close;
+
+ err = tty_register_ldisc(N_PPS, &pps_ldisc_ops);
+ if (err)
+ pr_err("can't register PPS line discipline\n");
+ else
+ pr_info("PPS line discipline registered\n");
+
+ return err;
+}
+
+static void __exit pps_tty_cleanup(void)
+{
+ int err;
+
+ err = tty_unregister_ldisc(N_PPS);
+ if (err)
+ pr_err("can't unregister PPS line discipline\n");
+ else
+ pr_info("PPS line discipline removed\n");
+}
+
+module_init(pps_tty_init);
+module_exit(pps_tty_cleanup);
+
+MODULE_ALIAS_LDISC(N_PPS);
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("PPS TTY device driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index db532ce..4bfb046 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -488,9 +488,13 @@ uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
{
struct uart_state *state = uport->state;
struct tty_port *port = &state->port;
+ struct tty_ldisc *ld = tty_ldisc_ref(port->tty);
+ struct timespec ts;
- uport->icount.dcd++;
+ if (ld && ld->ops->dcd_change)
+ getnstimeofday(&ts);
+ uport->icount.dcd++;
#ifdef CONFIG_HARD_PPS
if ((uport->flags & UPF_HARDPPS_CD) && status)
hardpps();
@@ -502,6 +506,11 @@ uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
else if (port->tty)
tty_hangup(port->tty);
}
+
+ if (ld && ld->ops->dcd_change)
+ ld->ops->dcd_change(port->tty, status, &ts);
+ if (ld)
+ tty_ldisc_deref(ld);
}
/**
--
1.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 7/8] serial 8250: enable PPS support.
2010-02-16 9:51 ` [PATCH 6/8] pps: serial clients support Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 8/8] serial amba-pl010: " Rodolfo Giometti
2010-02-19 21:53 ` [PATCH 6/8] pps: serial clients support Andrew Morton
1 sibling, 1 reply; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
Automagically function serial8250_enable_ms() is called when PPS ldisc
is selected.
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
drivers/serial/8250.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 737b4c9..e70187b 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2415,6 +2415,21 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
}
static void
+serial8250_set_ldisc(struct uart_port *port)
+{
+ int line = port->line;
+
+ if (line >= port->state->port.tty->driver->num)
+ return;
+
+ if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+ port->flags |= UPF_HARDPPS_CD;
+ serial8250_enable_ms(port);
+ } else
+ port->flags &= ~UPF_HARDPPS_CD;
+}
+
+static void
serial8250_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
@@ -2628,6 +2643,7 @@ static struct uart_ops serial8250_pops = {
.startup = serial8250_startup,
.shutdown = serial8250_shutdown,
.set_termios = serial8250_set_termios,
+ .set_ldisc = serial8250_set_ldisc,
.pm = serial8250_pm,
.type = serial8250_type,
.release_port = serial8250_release_port,
--
1.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 8/8] serial amba-pl010: enable PPS support.
2010-02-16 9:51 ` [PATCH 7/8] serial 8250: enable PPS support Rodolfo Giometti
@ 2010-02-16 9:51 ` Rodolfo Giometti
0 siblings, 0 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 9:51 UTC (permalink / raw)
To: linux-kernel
Cc: Andrew Morton, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev,
Rodolfo Giometti
Function pl010_enable_ms() is automagically called when PPS ldisc
is selected.
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
---
drivers/serial/amba-pl010.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 429a8ae..e4b3c2c 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -471,6 +471,20 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
spin_unlock_irqrestore(&uap->port.lock, flags);
}
+static void pl010_set_ldisc(struct uart_port *port)
+{
+ int line = port->line;
+
+ if (line >= port->state->port.tty->driver->num)
+ return;
+
+ if (port->state->port.tty->ldisc->ops->num == N_PPS) {
+ port->flags |= UPF_HARDPPS_CD;
+ pl010_enable_ms(port);
+ } else
+ port->flags &= ~UPF_HARDPPS_CD;
+}
+
static const char *pl010_type(struct uart_port *port)
{
return port->type == PORT_AMBA ? "AMBA" : NULL;
@@ -531,6 +545,7 @@ static struct uart_ops amba_pl010_pops = {
.startup = pl010_startup,
.shutdown = pl010_shutdown,
.set_termios = pl010_set_termios,
+ .set_ldisc = pl010_set_ldisc,
.type = pl010_type,
.release_port = pl010_release_port,
.request_port = pl010_request_port,
--
1.6.3.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: LinuxPPS new functionalities
2010-02-16 9:51 LinuxPPS new functionalities Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 1/8] pps: userland header file for PPS API Rodolfo Giometti
@ 2010-02-16 12:28 ` Alan Cox
1 sibling, 0 replies; 17+ messages in thread
From: Alan Cox @ 2010-02-16 12:28 UTC (permalink / raw)
To: Rodolfo Giometti
Cc: linux-kernel, Andrew Morton, David Woodhouse, Dave Jones,
Sam Ravnborg, Greg KH, Randy Dunlap, Kay Sievers, H. Peter Anvin,
Ingo Molnar, Michael Kerrisk, Christoph Hellwig,
Alexander Gordeev
On Tue, 16 Feb 2010 10:51:17 +0100
Rodolfo Giometti <giometti@linux.it> wrote:
> This patchset adds several PPS functionalities.
>
> All patches have a specific comment but I prefer say something more:
>
> * Patches 01-02 are just documentation about PPS support.
>
> * Patch 03 adds PPS client support skeleton.
>
> * Patches 04-06 add generic PPS serial support (with specific
> modifications requested by Alan Cox).
Thanks - the serial/tty stuff is much much cleaner in this patch set.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/8] pps: userland header file for PPS API.
2010-02-16 9:51 ` [PATCH 1/8] pps: userland header file for PPS API Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 2/8] pps: documentation programs and examples Rodolfo Giometti
@ 2010-02-16 12:33 ` Alexander Gordeev
2010-02-16 13:53 ` Rodolfo Giometti
1 sibling, 1 reply; 17+ messages in thread
From: Alexander Gordeev @ 2010-02-16 12:33 UTC (permalink / raw)
To: Rodolfo Giometti
Cc: linux-kernel, Andrew Morton, David Woodhouse, Dave Jones,
Sam Ravnborg, Greg KH, Randy Dunlap, Kay Sievers, Alan Cox,
H. Peter Anvin, Ingo Molnar, Michael Kerrisk, Christoph Hellwig,
Rodolfo Giometti
[-- Attachment #1: Type: text/plain, Size: 7738 bytes --]
Hi Rodolfo,
On Tue, 16 Feb 2010 10:51:18 +0100
Rodolfo Giometti <giometti@linux.it> wrote:
> 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. :)
Isn't libc a proper place for this file? This header file provides a
generic standardized interface (PPSAPI) to the custom Linux
implementation (linux/pps.h). I think this is just what libc is for.
I wanted to file a bug in Debian BTS last week to add this header to
libc6-dev package and also push it upstream but something distracted
me. If you agree that the header should be in libc then I can do it now.
> Signed-off-by: Rodolfo Giometti <giometti@linux.it>
> ---
> Documentation/pps/timepps.h | 198
> +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 198
> 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..d2628d2
> --- /dev/null
> +++ b/Documentation/pps/timepps.h
> @@ -0,0 +1,198 @@
> +/*
> + * 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 <errno.h>
> +#include <sys/time.h>
> +#include <sys/ioctl.h>
> +#include <linux/types.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 assert
> event */
> + unsigned long clear_sequence; /* seq. num. of clear
> event */
> + union pps_timeu assert_tu; /* time of assert event */
> + union pps_timeu clear_tu; /* time of clear event */
> + int current_mode; /* current mode bits */
> +};
> +
> +struct pps_params {
> + int api_version; /* API version # */
> + int mode; /* mode bits */
> + union pps_timeu assert_off_tu; /* offset compensation
> for assert */
> + union pps_timeu clear_off_tu; /* offset compensation
> for clear */ +};
> +
> +typedef int pps_handle_t; /* represents a PPS source
> */ +typedef unsigned long pps_seq_t; /* sequence number */
> +typedef struct ntp_fp ntp_fp_t; /* NTP-compatible
> time stamp */ +typedef union pps_timeu pps_timeu_t; /* generic
> data type for time stamps */ +typedef struct pps_info pps_info_t;
> +typedef struct pps_params pps_params_t;
> +
> +#define assert_timestamp assert_tu.tspec
> +#define clear_timestamp clear_tu.tspec
> +
> +#define assert_timestamp_ntpfp assert_tu.ntpfp
> +#define clear_timestamp_ntpfp clear_tu.ntpfp
> +
> +#define assert_offset assert_off_tu.tspec
> +#define clear_offset clear_off_tu.tspec
> +
> +#define assert_offset_ntpfp assert_off_tu.ntpfp
> +#define clear_offset_ntpfp clear_off_tu.ntpfp
> +
> +/*
> + * The PPS API
> + */
> +
> +static __inline int time_pps_create(int source, pps_handle_t *handle)
> +{
> + int ret;
> + struct pps_kparams dummy;
> +
> + if (!handle) {
> + errno = EINVAL;
> + return -1;
> + }
> +
> + /* First we check if current device is a valid PPS one by
> + * doing a dummy PPS_GETPARAMS...
> + */
> + ret = ioctl(source, PPS_GETPARAMS, &dummy);
> + if (ret) {
> + errno = EOPNOTSUPP;
> + return -1;
> + }
> +
> + /* ... then since in LinuxPPS there are no differences
> between a
> + * "PPS source" and a "PPS handle", we simply return the
> same value.
> + */
> + *handle = source;
> +
> + return 0;
> +}
> +
> +static __inline int time_pps_destroy(pps_handle_t handle)
> +{
> + return close(handle);
> +}
> +
> +static __inline int time_pps_getparams(pps_handle_t handle,
> + pps_params_t *ppsparams)
> +{
> + int ret;
> + struct pps_kparams __ppsparams;
> +
> + ret = ioctl(handle, PPS_GETPARAMS, &__ppsparams);
> +
> + ppsparams->api_version = __ppsparams.api_version;
> + ppsparams->mode = __ppsparams.mode;
> + ppsparams->assert_off_tu.tspec.tv_sec =
> __ppsparams.assert_off_tu.sec;
> + ppsparams->assert_off_tu.tspec.tv_nsec =
> __ppsparams.assert_off_tu.nsec;
> + ppsparams->clear_off_tu.tspec.tv_sec =
> __ppsparams.clear_off_tu.sec;
> + ppsparams->clear_off_tu.tspec.tv_nsec =
> __ppsparams.clear_off_tu.nsec; +
> + return ret;
> +}
> +
> +static __inline int time_pps_setparams(pps_handle_t handle,
> + const pps_params_t
> *ppsparams) +{
> + struct pps_kparams __ppsparams;
> +
> + __ppsparams.api_version = ppsparams->api_version;
> + __ppsparams.mode = ppsparams->mode;
> + __ppsparams.assert_off_tu.sec =
> ppsparams->assert_off_tu.tspec.tv_sec;
> + __ppsparams.assert_off_tu.nsec =
> ppsparams->assert_off_tu.tspec.tv_nsec;
> + __ppsparams.clear_off_tu.sec =
> ppsparams->clear_off_tu.tspec.tv_sec;
> + __ppsparams.clear_off_tu.nsec =
> ppsparams->clear_off_tu.tspec.tv_nsec; +
> + return ioctl(handle, PPS_SETPARAMS, &__ppsparams);
> +}
> +
> +/* Get capabilities for handle */
> +static __inline int time_pps_getcap(pps_handle_t handle, int *mode)
> +{
> + return ioctl(handle, PPS_GETCAP, mode);
> +}
> +
> +static __inline int time_pps_fetch(pps_handle_t handle, const int
> tsformat,
> + pps_info_t *ppsinfobuf,
> + const struct timespec
> *timeout) +{
> + struct pps_fdata __fdata;
> + int ret;
> +
> + /* Sanity checks */
> + if (tsformat != PPS_TSFMT_TSPEC) {
> + errno = EINVAL;
> + return -1;
> + }
> +
> + if (timeout) {
> + __fdata.timeout.sec = timeout->tv_sec;
> + __fdata.timeout.nsec = timeout->tv_nsec;
> + __fdata.timeout.flags = ~PPS_TIME_INVALID;
> + } else
> + __fdata.timeout.flags = PPS_TIME_INVALID;
> +
> + ret = ioctl(handle, PPS_FETCH, &__fdata);
> +
> + ppsinfobuf->assert_sequence = __fdata.info.assert_sequence;
> + ppsinfobuf->clear_sequence = __fdata.info.clear_sequence;
> + ppsinfobuf->assert_tu.tspec.tv_sec =
> __fdata.info.assert_tu.sec;
> + ppsinfobuf->assert_tu.tspec.tv_nsec =
> __fdata.info.assert_tu.nsec;
> + ppsinfobuf->clear_tu.tspec.tv_sec =
> __fdata.info.clear_tu.sec;
> + ppsinfobuf->clear_tu.tspec.tv_nsec =
> __fdata.info.clear_tu.nsec;
> + ppsinfobuf->current_mode = __fdata.info.current_mode;
> +
> + return ret;
> +}
> +
> +static __inline int time_pps_kcbind(pps_handle_t handle,
> + const int kernel_consumer,
> + const int edge, const int
> tsformat) +{
> + /* LinuxPPS doesn't implement kernel consumer feature */
> + errno = EOPNOTSUPP;
> + return -1;
> +}
> +
> +#endif /* _SYS_TIMEPPS_H_ */
--
Alexander
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 489 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/8] pps: documentation programs and examples.
2010-02-16 9:51 ` [PATCH 2/8] pps: documentation programs and examples Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 3/8] pps: LinuxPPS clients support Rodolfo Giometti
@ 2010-02-16 12:44 ` Alexander Gordeev
2010-02-16 13:56 ` Rodolfo Giometti
1 sibling, 1 reply; 17+ messages in thread
From: Alexander Gordeev @ 2010-02-16 12:44 UTC (permalink / raw)
To: Rodolfo Giometti
Cc: linux-kernel, Andrew Morton, David Woodhouse, Dave Jones,
Sam Ravnborg, Greg KH, Randy Dunlap, Kay Sievers, Alan Cox,
H. Peter Anvin, Ingo Molnar, Michael Kerrisk, Christoph Hellwig,
Rodolfo Giometti
[-- Attachment #1: Type: text/plain, Size: 6755 bytes --]
On Tue, 16 Feb 2010 10:51:19 +0100
Rodolfo Giometti <giometti@linux.it> wrote:
> Here some utilities and examples about the PPS API and the LinuxPPS
> support.
>
> * 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.
Maybe these tools should be in a separate package (say pps-tools)? I've
written several tools too. They are based on your code. I think there
should be at least two of them:
* ppsctl to get/set params, get capabilities and bind/unbind kernel
consumer
* ppstest to fetch data and provide several representations for it
I can assist in this task too.
> Signed-off-by: Rodolfo Giometti <giometti@linux.it>
> ---
> Documentation/pps/Makefile | 27 ++++++++
> Documentation/pps/ppsfind | 17 +++++
> Documentation/pps/ppstest.c | 150
> +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194
> insertions(+), 0 deletions(-) create mode 100644
> Documentation/pps/Makefile create mode 100644
> Documentation/pps/ppsfind create mode 100644
> Documentation/pps/ppstest.c
>
> diff --git a/Documentation/pps/Makefile b/Documentation/pps/Makefile
> new file mode 100644
> index 0000000..3848aba
> --- /dev/null
> +++ b/Documentation/pps/Makefile
> @@ -0,0 +1,27 @@
> +TARGETS = ppstest
> +
> +CFLAGS += -Wall -O2 -D_GNU_SOURCE
> +CFLAGS += -I . -I ../../include/
> +CFLAGS += -ggdb
> +
> +# -- 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 0
> diff --git a/Documentation/pps/ppstest.c b/Documentation/pps/ppstest.c
> new file mode 100644
> index 0000000..30c8f6d
> --- /dev/null
> +++ b/Documentation/pps/ppstest.c
> @@ -0,0 +1,150 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +
> +#include <timepps.h>
> +
> +int find_source(char *path, pps_handle_t *handle, int *avail_mode)
> +{
> + pps_params_t params;
> + int ret;
> +
> + printf("trying PPS source \"%s\"\n", path);
> +
> + /* Try to find the source by using the supplied "path" name
> */
> + ret = open(path, O_RDWR);
> + if (ret < 0) {
> + fprintf(stderr, "unable to open device
> \"%s\" (%m)\n", path);
> + return ret;
> + }
> +
> + /* Open the PPS source (and check the file descriptor) */
> + ret = time_pps_create(ret, handle);
> + if (ret < 0) {
> + fprintf(stderr, "cannot create a PPS source from
> device "
> + "\"%s\" (%m)\n", path);
> + return -1;
> + }
> + printf("found PPS source \"%s\"\n", path);
> +
> + /* Find out what features are supported */
> + ret = time_pps_getcap(*handle, avail_mode);
> + if (ret < 0) {
> + fprintf(stderr, "cannot get capabilities (%m)\n");
> + return -1;
> + }
> + if ((*avail_mode & PPS_CAPTUREASSERT) == 0) {
> + fprintf(stderr, "cannot CAPTUREASSERT\n");
> + return -1;
> + }
> + if ((*avail_mode & PPS_OFFSETASSERT) == 0) {
> + fprintf(stderr, "cannot OFFSETASSERT\n");
> + return -1;
> + }
> +
> + /* Capture assert timestamps, and compensate for a 675 nsec
> + * propagation delay */
> + ret = time_pps_getparams(*handle, ¶ms);
> + if (ret < 0) {
> + fprintf(stderr, "cannot get parameters (%m)\n");
> + return -1;
> + }
> + params.assert_offset.tv_sec = 0;
> + params.assert_offset.tv_nsec = 675;
> + params.mode |= PPS_CAPTUREASSERT | PPS_OFFSETASSERT;
> + params.mode &= ~(PPS_CAPTURECLEAR | PPS_OFFSETCLEAR);
> + ret = time_pps_setparams(*handle, ¶ms);
> + if (ret < 0) {
> + fprintf(stderr, "cannot set parameters (%m)\n");
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +int fetch_source(int i, pps_handle_t *handle, int *avail_mode)
> +{
> + struct timespec timeout;
> + pps_info_t infobuf;
> + int ret;
> +
> + /* create a zero-valued timeout */
> + timeout.tv_sec = 3;
> + timeout.tv_nsec = 0;
> +
> +retry:
> + if (*avail_mode & PPS_CANWAIT) /* waits for the next event */
> + ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC,
> &infobuf,
> + &timeout);
> + else {
> + sleep(1);
> + ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC,
> &infobuf,
> + &timeout);
> + }
> + if (ret < 0) {
> + if (ret == -EINTR) {
> + fprintf(stderr, "time_pps_fetch() got a
> signal!\n");
> + goto retry;
> + }
> +
> + fprintf(stderr, "time_pps_fetch() error %d (%m)\n",
> ret);
> + return -1;
> + }
> +
> + printf("source %d - "
> + "assert %ld.%09ld, sequence: %ld - "
> + "clear %ld.%09ld, sequence: %ld\n",
> + i,
> + infobuf.assert_timestamp.tv_sec,
> + infobuf.assert_timestamp.tv_nsec,
> + infobuf.assert_sequence,
> + infobuf.clear_timestamp.tv_sec,
> + infobuf.clear_timestamp.tv_nsec,
> infobuf.clear_sequence); +
> + return 0;
> +}
> +
> +void usage(char *name)
> +{
> + fprintf(stderr, "usage: %s <ppsdev> [<ppsdev> ...]\n", name);
> + exit(EXIT_FAILURE);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + int num;
> + pps_handle_t handle[4];
> + int avail_mode[4];
> + int i = 0;
> + int ret;
> +
> + /* Check the command line */
> + if (argc < 2)
> + usage(argv[0]);
> +
> + for (i = 1; i < argc && i <= 4; i++) {
> + ret = find_source(argv[i], &handle[i - 1],
> &avail_mode[i - 1]);
> + if (ret < 0)
> + exit(EXIT_FAILURE);
> + }
> +
> + num = i - 1;
> + printf("ok, found %d source(s), now start fetching
> data...\n", num); +
> + /* loop, printing the most recent timestamp every second or
> so */
> + while (1) {
> + for (i = 0; i < num; i++) {
> + ret = fetch_source(i, &handle[i],
> &avail_mode[i]);
> + if (ret < 0 && errno != ETIMEDOUT)
> + exit(EXIT_FAILURE);
> + }
> + }
> +
> + for (; i >= 0; i--)
> + time_pps_destroy(handle[i]);
> +
> + return 0;
> +}
--
Alexander
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 489 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/8] pps: userland header file for PPS API.
2010-02-16 12:33 ` [PATCH 1/8] pps: userland header file for PPS API Alexander Gordeev
@ 2010-02-16 13:53 ` Rodolfo Giometti
0 siblings, 0 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 13:53 UTC (permalink / raw)
To: Alexander Gordeev
Cc: linux-kernel, Andrew Morton, David Woodhouse, Dave Jones,
Sam Ravnborg, Greg KH, Randy Dunlap, Kay Sievers, Alan Cox,
H. Peter Anvin, Ingo Molnar, Michael Kerrisk, Christoph Hellwig
On Tue, Feb 16, 2010 at 03:33:01PM +0300, Alexander Gordeev wrote:
> Hi Rodolfo,
>
> On Tue, 16 Feb 2010 10:51:18 +0100
> Rodolfo Giometti <giometti@linux.it> wrote:
>
> > 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. :)
>
> Isn't libc a proper place for this file? This header file provides a
> generic standardized interface (PPSAPI) to the custom Linux
> implementation (linux/pps.h). I think this is just what libc is for.
You are right, but I added that file for documentation purpose also.
Just to illustrate how to implement an high level API with my simple
char device interface.
> I wanted to file a bug in Debian BTS last week to add this header to
> libc6-dev package and also push it upstream but something distracted
> me. If you agree that the header should be in libc then I can do it now.
I agree. :)
Can you please put me in Cc in your letters with the Debian people?
Thanks a lot,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti@enneenne.com
Linux Device Driver giometti@linux.it
Embedded Systems phone: +39 349 2432127
UNIX programming skype: rodolfo.giometti
Freelance ICT Italia - Consulente ICT Italia - www.consulenti-ict.it
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/8] pps: documentation programs and examples.
2010-02-16 12:44 ` [PATCH 2/8] pps: documentation programs and examples Alexander Gordeev
@ 2010-02-16 13:56 ` Rodolfo Giometti
0 siblings, 0 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-16 13:56 UTC (permalink / raw)
To: Alexander Gordeev
Cc: linux-kernel, Andrew Morton, David Woodhouse, Dave Jones,
Sam Ravnborg, Greg KH, Randy Dunlap, Kay Sievers, Alan Cox,
H. Peter Anvin, Ingo Molnar, Michael Kerrisk, Christoph Hellwig
On Tue, Feb 16, 2010 at 03:44:56PM +0300, Alexander Gordeev wrote:
> On Tue, 16 Feb 2010 10:51:19 +0100
> Rodolfo Giometti <giometti@linux.it> wrote:
>
> > Here some utilities and examples about the PPS API and the LinuxPPS
> > support.
> >
> > * 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.
>
> Maybe these tools should be in a separate package (say pps-tools)? I've
> written several tools too. They are based on your code. I think there
> should be at least two of them:
>
> * ppsctl to get/set params, get capabilities and bind/unbind kernel
> consumer
>
> * ppstest to fetch data and provide several representations for it
>
> I can assist in this task too.
Great! It's ok for me. Please, let me know how we can proceed.
Thanks a lot,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti@enneenne.com
Linux Device Driver giometti@linux.it
Embedded Systems phone: +39 349 2432127
UNIX programming skype: rodolfo.giometti
Freelance ICT Italia - Consulente ICT Italia - www.consulenti-ict.it
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops()
2010-02-16 9:51 ` [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops() Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 6/8] pps: serial clients support Rodolfo Giometti
@ 2010-02-19 21:45 ` Andrew Morton
1 sibling, 0 replies; 17+ messages in thread
From: Andrew Morton @ 2010-02-19 21:45 UTC (permalink / raw)
To: Rodolfo Giometti
Cc: linux-kernel, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev
On Tue, 16 Feb 2010 10:51:22 +0100
Rodolfo Giometti <giometti@linux.it> wrote:
> };
> +
> +void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
> +{
> + *ops = tty_ldisc_N_TTY;
> + ops->owner = NULL;
> + ops->refcount = ops->flags = 0;
> +}
> +EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
Most (nearly all) functions in n_tty.c have been documented in
kerneldoc form. Let's continue that please.
n_tty_inherit_ops() is of course pretty simple, but OTOH it's a global,
export-to-modules interface.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 6/8] pps: serial clients support.
2010-02-16 9:51 ` [PATCH 6/8] pps: serial clients support Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 7/8] serial 8250: enable PPS support Rodolfo Giometti
@ 2010-02-19 21:53 ` Andrew Morton
2010-02-21 19:21 ` Rodolfo Giometti
1 sibling, 1 reply; 17+ messages in thread
From: Andrew Morton @ 2010-02-19 21:53 UTC (permalink / raw)
To: Rodolfo Giometti
Cc: linux-kernel, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev
On Tue, 16 Feb 2010 10:51:23 +0100
Rodolfo Giometti <giometti@linux.it> wrote:
> Adds support, by using the PPS line discipline, for the PPS sources
> connected with the CD (Carrier Detect) pin of a serial port.
>
> ...
>
> +static int (*n_tty_open)(struct tty_struct *tty);
> +
> +static int pps_tty_open(struct tty_struct *tty)
> +{
> + struct pps_source_info info;
> + struct tty_driver *drv = tty->driver;
> + int index = tty->index + drv->name_base;
> + int ret;
> +
> + info.owner = THIS_MODULE;
> + info.dev = NULL;
> + snprintf(info.name, PPS_MAX_NAME_LEN, "%s%d", drv->driver_name, index);
> + snprintf(info.path, PPS_MAX_NAME_LEN, "/dev/%s%d", drv->name, index);
> + info.mode = PPS_CAPTUREBOTH | \
> + PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
> + PPS_CANWAIT | PPS_TSFMT_TSPEC;
> +
> + ret = pps_register_source(&info, PPS_CAPTUREBOTH | \
> + PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
> + if (ret < 0) {
> + pr_err("cannot register PPS source \"%s\"\n", info.path);
> + return ret;
> + }
> + tty->disc_data = (void *) ret;
> +
> + /* Should open N_TTY ldisc too */
> + ret = n_tty_open(tty);
> + if (ret < 0)
> + pps_unregister_source((int) tty->disc_data);
> +
> + pr_info("PPS source #%d \"%s\" added\n", ret, info.path);
> +
> + return 0;
> +}
hm. The n_tty_open/close layering is a bit grubby but I guess we don't
have a need to create anything more comprehensive at this stage.
A small stylistic thing: the code's a bit confusing at present because
the names n_tty_open/n_tty_close are identical to the global functions
over in n_tty.c. A user of ctags will be tricked. Also, the _way_ in
which these function pointers are called:
ret = n_tty_open(tty);
make it look like the code is calling
drivers/char/n_tty.c:n_tty_open(). Except it isn't.
So I think it's better to do it with
ret = (*n_tty_open)(tty);
to avoid misleading the reader.
And perhaps to rename these variables to avoid the duplication with the
global functions.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 6/8] pps: serial clients support.
2010-02-19 21:53 ` [PATCH 6/8] pps: serial clients support Andrew Morton
@ 2010-02-21 19:21 ` Rodolfo Giometti
0 siblings, 0 replies; 17+ messages in thread
From: Rodolfo Giometti @ 2010-02-21 19:21 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, David Woodhouse, Dave Jones, Sam Ravnborg, Greg KH,
Randy Dunlap, Kay Sievers, Alan Cox, H. Peter Anvin, Ingo Molnar,
Michael Kerrisk, Christoph Hellwig, Alexander Gordeev
On Fri, Feb 19, 2010 at 01:53:59PM -0800, Andrew Morton wrote:
>
> hm. The n_tty_open/close layering is a bit grubby but I guess we don't
> have a need to create anything more comprehensive at this stage.
>
> A small stylistic thing: the code's a bit confusing at present because
> the names n_tty_open/n_tty_close are identical to the global functions
> over in n_tty.c. A user of ctags will be tricked. Also, the _way_ in
> which these function pointers are called:
>
> ret = n_tty_open(tty);
>
> make it look like the code is calling
> drivers/char/n_tty.c:n_tty_open(). Except it isn't.
>
> So I think it's better to do it with
>
> ret = (*n_tty_open)(tty);
>
> to avoid misleading the reader.
>
> And perhaps to rename these variables to avoid the duplication with the
> global functions.
It could be acceptable using functions
alias_n_tty_open()/alias_n_tty_close() modifying the code as follow?
diff --git a/drivers/pps/clients/pps-ldisc.c
b/drivers/pps/clients/pps-ldisc.c
index 59e6301..15c4622 100644
--- a/drivers/pps/clients/pps-ldisc.c
+++ b/drivers/pps/clients/pps-ldisc.c
@@ -53,7 +53,7 @@ static void pps_tty_dcd_change(struct tty_struct
*tty, unsigne
status ? "assert" : "clear", jiffies, id);
}
-static int (*n_tty_open)(struct tty_struct *tty);
+static int (*alias_n_tty_open)(struct tty_struct *tty);
static int pps_tty_open(struct tty_struct *tty)
{
@@ -79,7 +79,7 @@ static int pps_tty_open(struct tty_struct *tty)
tty->disc_data = (void *) ret;
/* Should open N_TTY ldisc too */
- ret = n_tty_open(tty);
+ ret = alias_n_tty_open(tty);
if (ret < 0)
pps_unregister_source((int) tty->disc_data);
@@ -88,14 +88,14 @@ static int pps_tty_open(struct tty_struct *tty)
return 0;
}
-static void (*n_tty_close)(struct tty_struct *tty);
+static void (*alias_n_tty_close)(struct tty_struct *tty);
static void pps_tty_close(struct tty_struct *tty)
{
int id = (int) tty->disc_data;
pps_unregister_source(id);
- n_tty_close(tty);
+ alias_n_tty_close(tty);
pr_info("PPS source #%d removed\n", id);
}
Ciao,
Rodolfo
--
GNU/Linux Solutions e-mail: giometti@enneenne.com
Linux Device Driver giometti@linux.it
Embedded Systems phone: +39 349 2432127
UNIX programming skype: rodolfo.giometti
Freelance ICT Italia - Consulente ICT Italia - www.consulenti-ict.it
^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2010-02-21 19:21 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-16 9:51 LinuxPPS new functionalities Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 1/8] pps: userland header file for PPS API Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 2/8] pps: documentation programs and examples Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 3/8] pps: LinuxPPS clients support Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 4/8] ldisc: new dcd_change() method for line disciplines Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops() Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 6/8] pps: serial clients support Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 7/8] serial 8250: enable PPS support Rodolfo Giometti
2010-02-16 9:51 ` [PATCH 8/8] serial amba-pl010: " Rodolfo Giometti
2010-02-19 21:53 ` [PATCH 6/8] pps: serial clients support Andrew Morton
2010-02-21 19:21 ` Rodolfo Giometti
2010-02-19 21:45 ` [PATCH 5/8] ldisc n_tty: add new method n_tty_inherit_ops() Andrew Morton
2010-02-16 12:44 ` [PATCH 2/8] pps: documentation programs and examples Alexander Gordeev
2010-02-16 13:56 ` Rodolfo Giometti
2010-02-16 12:33 ` [PATCH 1/8] pps: userland header file for PPS API Alexander Gordeev
2010-02-16 13:53 ` Rodolfo Giometti
2010-02-16 12:28 ` LinuxPPS new functionalities Alan Cox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox