summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Chavent <Paul.Chavent@onera.fr>2013-09-16 02:41:00 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-26 12:45:40 -0400
commit833efc0ed19ce9ed7a84dfd3684eb9d892fe9ded (patch)
tree1a693b88ee1c976704262a09b788ef0c4e62f87c
parentd14654dff7a3520b5220367b848732a0a8ccdabe (diff)
USB: serial: invoke dcd_change ldisc's handler.
The DCD pin of the serial port can receive a PPS signal. By calling the port line discipline dcd handle, this patch allow to monitor PPS through USB serial devices. However the performance aren't as good as the uart drivers, so document this point too. Signed-off-by: Paul Chavent <paul.chavent@onera.fr> Acked-by: Rodolfo Giometti <giometti@enneenne.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--Documentation/pps/pps.txt15
-rw-r--r--drivers/usb/serial/generic.c10
2 files changed, 25 insertions, 0 deletions
diff --git a/Documentation/pps/pps.txt b/Documentation/pps/pps.txt
index d35dcdd82ff6..c03b1be5eb15 100644
--- a/Documentation/pps/pps.txt
+++ b/Documentation/pps/pps.txt
@@ -66,6 +66,21 @@ In LinuxPPS the PPS sources are simply char devices usually mapped
66into files /dev/pps0, /dev/pps1, etc.. 66into files /dev/pps0, /dev/pps1, etc..
67 67
68 68
69PPS with USB to serial devices
70------------------------------
71
72It is possible to grab the PPS from an USB to serial device. However,
73you should take into account the latencies and jitter introduced by
74the USB stack. Users has reported clock instability around +-1ms when
75synchronized with PPS through USB. This isn't suited for time server
76synchronization.
77
78If your device doesn't report PPS, you can check that the feature is
79supported by its driver. Most of the time, you only need to add a call
80to usb_serial_handle_dcd_change after checking the DCD status (see
81ch341 and pl2303 examples).
82
83
69Coding example 84Coding example
70-------------- 85--------------
71 86
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 1f31e6b4c251..3a5dac879094 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -570,6 +570,16 @@ void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
570 570
571 dev_dbg(&usb_port->dev, "%s - status %d\n", __func__, status); 571 dev_dbg(&usb_port->dev, "%s - status %d\n", __func__, status);
572 572
573 if (tty) {
574 struct tty_ldisc *ld = tty_ldisc_ref(tty);
575
576 if (ld) {
577 if (ld->ops->dcd_change)
578 ld->ops->dcd_change(tty, status);
579 tty_ldisc_deref(ld);
580 }
581 }
582
573 if (status) 583 if (status)
574 wake_up_interruptible(&port->open_wait); 584 wake_up_interruptible(&port->open_wait);
575 else if (tty && !C_CLOCAL(tty)) 585 else if (tty && !C_CLOCAL(tty))