From: Rodolfo Giometti <giometti@linux.it>
To: linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
David Woodhouse <dwmw2@infradead.org>,
Dave Jones <davej@redhat.com>, Sam Ravnborg <sam@ravnborg.org>,
Greg KH <greg@kroah.com>, Randy Dunlap <randy.dunlap@oracle.com>,
Kay Sievers <kay.sievers@vrfy.org>,
Alan Cox <alan@lxorguk.ukuu.org.uk>,
"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@elte.hu>,
Rodolfo Giometti <giometti@linux.it>
Subject: [PATCH 08/10] PPS: serial clients support.
Date: Thu, 2 Oct 2008 09:41:47 +0200 [thread overview]
Message-ID: <1222933309-2524-9-git-send-email-giometti@linux.it> (raw)
In-Reply-To: <1222933309-2524-8-git-send-email-giometti@linux.it>
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.
+ *
+ * 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.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 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 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);
+}
+
+struct tty_ldisc_ops pps_ldisc_ops = {
+ .magic = PPS_TTY_MAGIC,
+ .name = "pps_tty",
+ .dcd_change = pps_tty_dcd_change,
+ .open = pps_tty_open,
+ .close = pps_tty_close,
+
+ /* Now we should use N_TTY ldisc methods in order to have
+ * normal tty behaviour
+ */
+ .flush_buffer = n_tty_flush_buffer,
+ .chars_in_buffer = n_tty_chars_in_buffer,
+ .read = n_tty_read,
+ .write = n_tty_write,
+ .ioctl = n_tty_ioctl,
+ .set_termios = n_tty_set_termios,
+ .poll = n_tty_poll,
+ .receive_buf = n_tty_receive_buf,
+ .write_wakeup = n_tty_write_wakeup
+};
+
+/*
+ * Module stuff
+ */
+
+static int __init pps_tty_init(void)
+{
+ int err;
+
+ 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/drivers/serial/8250.c b/drivers/serial/8250.c
index 342e12f..1759d87 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2247,6 +2247,18 @@ 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->info->port.tty->driver->num)
+ return;
+
+ if (port->info->port.tty->ldisc.ops->num == N_PPS)
+ serial8250_enable_ms(port);
+}
+
+static void
serial8250_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
@@ -2450,6 +2462,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,
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 3b2f6c0..1aa894c 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -488,9 +488,13 @@ static inline void
uart_handle_dcd_change(struct uart_port *port, unsigned int status)
{
struct uart_info *info = port->info;
+ struct tty_ldisc *ld = tty_ldisc_ref(info->port.tty);
+ struct timespec ts;
- port->icount.dcd++;
+ if (ld->ops->dcd_change)
+ getnstimeofday(&ts);
+ port->icount.dcd++;
#ifdef CONFIG_HARD_PPS
if ((port->flags & UPF_HARDPPS_CD) && status)
hardpps();
@@ -502,6 +506,10 @@ uart_handle_dcd_change(struct uart_port *port, unsigned int status)
else if (info->port.tty)
tty_hangup(info->port.tty);
}
+
+ if (ld->ops->dcd_change)
+ ld->ops->dcd_change(port, status, &ts);
+ tty_ldisc_deref(ld);
}
/**
--
1.5.4.3
next prev parent reply other threads:[~2008-10-02 7:45 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-02 7:41 LinuxPPS (RESUBMIT 7): the PPS Linux implementation Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 01/10] LinuxPPS core support Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 02/10] PPS: userland header file for PPS API Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 03/10] PPS: documentation programs and examples Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 04/10] PPS: LinuxPPS clients support Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 05/10] ldisc: new dcd_change() method for line disciplines Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 06/10] ldisc n_tty: export all N_TTY ldisc methods Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 07/10] tty: new PPS line discipline Rodolfo Giometti
2008-10-02 7:41 ` Rodolfo Giometti [this message]
2008-10-02 7:41 ` [PATCH 09/10] PPS: parallel port clients support Rodolfo Giometti
2008-10-02 7:41 ` [PATCH 10/10] PPS: low level IRQ timestamps recording Rodolfo Giometti
2008-10-08 22:57 ` john stultz
2008-10-09 8:42 ` Rodolfo Giometti
2008-10-02 15:25 ` [PATCH 05/10] ldisc: new dcd_change() method for line disciplines H. Peter Anvin
2008-10-02 15:58 ` Alan Cox
-- strict thread matches above, loose matches on Subject: below --
2008-09-10 7:52 LinuxPPS (RESUBMIT 7): the PPS Linux implementation Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 01/10] LinuxPPS core support Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 02/10] PPS: userland header file for PPS API Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 03/10] PPS: documentation programs and examples Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 04/10] PPS: LinuxPPS clients support Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 05/10] ldisc: new dcd_change() method for line disciplines Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 06/10] ldisc n_tty: export all N_TTY ldisc methods Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 07/10] tty: new PPS line discipline Rodolfo Giometti
2008-09-10 7:52 ` [PATCH 08/10] PPS: serial clients support Rodolfo Giometti
2008-08-20 13:16 LinuxPPS (RESUBMIT 7): the PPS Linux implementation Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 01/10] LinuxPPS core support Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 02/10] PPS: userland header file for PPS API Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 03/10] PPS: documentation programs and examples Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 04/10] PPS: LinuxPPS clients support Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 05/10] ldisc: new dcd_change() method for line disciplines Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 06/10] ldisc n_tty: export all N_TTY ldisc methods Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 07/10] tty: new PPS line discipline Rodolfo Giometti
2008-08-20 13:16 ` [PATCH 08/10] PPS: serial clients support Rodolfo Giometti
2008-08-19 21:50 LinuxPPS (RESUBMIT 6): the PPS Linux implementation Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 01/10] LinuxPPS core support Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 02/10] PPS: userland header file for PPS API Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 03/10] PPS: documentation programs and examples Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 04/10] PPS: LinuxPPS clients support Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 05/10] ldisc: new dcd_change() method for line disciplines Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 06/10] ldisc n_tty: export all N_TTY ldisc methods Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 07/10] tty: new PPS line discipline Rodolfo Giometti
2008-08-19 21:50 ` [PATCH 08/10] PPS: serial clients support Rodolfo Giometti
2008-08-19 21:56 ` Alan Cox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1222933309-2524-9-git-send-email-giometti@linux.it \
--to=giometti@linux.it \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=davej@redhat.com \
--cc=dwmw2@infradead.org \
--cc=greg@kroah.com \
--cc=hpa@zytor.com \
--cc=kay.sievers@vrfy.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=randy.dunlap@oracle.com \
--cc=sam@ravnborg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.