diff options
Diffstat (limited to 'drivers/pps/clients/pps-ldisc.c')
-rw-r--r-- | drivers/pps/clients/pps-ldisc.c | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index 8e1932d29fd..79451f2dea6 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
23 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
24 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
@@ -27,30 +29,18 @@ | |||
27 | #define PPS_TTY_MAGIC 0x0001 | 29 | #define PPS_TTY_MAGIC 0x0001 |
28 | 30 | ||
29 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, | 31 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, |
30 | struct timespec *ts) | 32 | struct pps_event_time *ts) |
31 | { | 33 | { |
32 | int id = (long)tty->disc_data; | 34 | struct pps_device *pps = (struct pps_device *)tty->disc_data; |
33 | struct timespec __ts; | 35 | |
34 | struct pps_ktime pps_ts; | 36 | BUG_ON(pps == NULL); |
35 | |||
36 | /* First of all we get the time stamp... */ | ||
37 | getnstimeofday(&__ts); | ||
38 | |||
39 | /* Does caller give us a timestamp? */ | ||
40 | if (ts) { /* Yes. Let's use it! */ | ||
41 | pps_ts.sec = ts->tv_sec; | ||
42 | pps_ts.nsec = ts->tv_nsec; | ||
43 | } else { /* No. Do it ourself! */ | ||
44 | pps_ts.sec = __ts.tv_sec; | ||
45 | pps_ts.nsec = __ts.tv_nsec; | ||
46 | } | ||
47 | 37 | ||
48 | /* Now do the PPS event report */ | 38 | /* Now do the PPS event report */ |
49 | pps_event(id, &pps_ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR, | 39 | pps_event(pps, ts, status ? PPS_CAPTUREASSERT : |
50 | NULL); | 40 | PPS_CAPTURECLEAR, NULL); |
51 | 41 | ||
52 | pr_debug("PPS %s at %lu on source #%d\n", | 42 | dev_dbg(pps->dev, "PPS %s at %lu\n", |
53 | status ? "assert" : "clear", jiffies, id); | 43 | status ? "assert" : "clear", jiffies); |
54 | } | 44 | } |
55 | 45 | ||
56 | static int (*alias_n_tty_open)(struct tty_struct *tty); | 46 | static int (*alias_n_tty_open)(struct tty_struct *tty); |
@@ -60,6 +50,7 @@ static int pps_tty_open(struct tty_struct *tty) | |||
60 | struct pps_source_info info; | 50 | struct pps_source_info info; |
61 | struct tty_driver *drv = tty->driver; | 51 | struct tty_driver *drv = tty->driver; |
62 | int index = tty->index + drv->name_base; | 52 | int index = tty->index + drv->name_base; |
53 | struct pps_device *pps; | ||
63 | int ret; | 54 | int ret; |
64 | 55 | ||
65 | info.owner = THIS_MODULE; | 56 | info.owner = THIS_MODULE; |
@@ -70,34 +61,42 @@ static int pps_tty_open(struct tty_struct *tty) | |||
70 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ | 61 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ |
71 | PPS_CANWAIT | PPS_TSFMT_TSPEC; | 62 | PPS_CANWAIT | PPS_TSFMT_TSPEC; |
72 | 63 | ||
73 | ret = pps_register_source(&info, PPS_CAPTUREBOTH | \ | 64 | pps = pps_register_source(&info, PPS_CAPTUREBOTH | \ |
74 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); | 65 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); |
75 | if (ret < 0) { | 66 | if (pps == NULL) { |
76 | pr_err("cannot register PPS source \"%s\"\n", info.path); | 67 | pr_err("cannot register PPS source \"%s\"\n", info.path); |
77 | return ret; | 68 | return -ENOMEM; |
78 | } | 69 | } |
79 | tty->disc_data = (void *)(long)ret; | 70 | tty->disc_data = pps; |
80 | 71 | ||
81 | /* Should open N_TTY ldisc too */ | 72 | /* Should open N_TTY ldisc too */ |
82 | ret = alias_n_tty_open(tty); | 73 | ret = alias_n_tty_open(tty); |
83 | if (ret < 0) | 74 | if (ret < 0) { |
84 | pps_unregister_source((long)tty->disc_data); | 75 | pr_err("cannot open tty ldisc \"%s\"\n", info.path); |
76 | goto err_unregister; | ||
77 | } | ||
85 | 78 | ||
86 | pr_info("PPS source #%d \"%s\" added\n", ret, info.path); | 79 | dev_info(pps->dev, "source \"%s\" added\n", info.path); |
87 | 80 | ||
88 | return 0; | 81 | return 0; |
82 | |||
83 | err_unregister: | ||
84 | tty->disc_data = NULL; | ||
85 | pps_unregister_source(pps); | ||
86 | return ret; | ||
89 | } | 87 | } |
90 | 88 | ||
91 | static void (*alias_n_tty_close)(struct tty_struct *tty); | 89 | static void (*alias_n_tty_close)(struct tty_struct *tty); |
92 | 90 | ||
93 | static void pps_tty_close(struct tty_struct *tty) | 91 | static void pps_tty_close(struct tty_struct *tty) |
94 | { | 92 | { |
95 | int id = (long)tty->disc_data; | 93 | struct pps_device *pps = (struct pps_device *)tty->disc_data; |
96 | 94 | ||
97 | pps_unregister_source(id); | ||
98 | alias_n_tty_close(tty); | 95 | alias_n_tty_close(tty); |
99 | 96 | ||
100 | pr_info("PPS source #%d removed\n", id); | 97 | tty->disc_data = NULL; |
98 | dev_info(pps->dev, "removed\n"); | ||
99 | pps_unregister_source(pps); | ||
101 | } | 100 | } |
102 | 101 | ||
103 | static struct tty_ldisc_ops pps_ldisc_ops; | 102 | static struct tty_ldisc_ops pps_ldisc_ops; |