diff options
Diffstat (limited to 'drivers/pps/clients/pps-ldisc.c')
-rw-r--r-- | drivers/pps/clients/pps-ldisc.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index 20fc9f7645c8..1517f5498ec0 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c | |||
@@ -29,7 +29,7 @@ | |||
29 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, | 29 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, |
30 | struct pps_event_time *ts) | 30 | struct pps_event_time *ts) |
31 | { | 31 | { |
32 | int id = (long)tty->disc_data; | 32 | struct pps_device *pps = (struct pps_device *)tty->disc_data; |
33 | struct pps_event_time __ts; | 33 | struct pps_event_time __ts; |
34 | 34 | ||
35 | /* First of all we get the time stamp... */ | 35 | /* First of all we get the time stamp... */ |
@@ -39,12 +39,14 @@ static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, | |||
39 | if (!ts) /* No. Do it ourself! */ | 39 | if (!ts) /* No. Do it ourself! */ |
40 | ts = &__ts; | 40 | ts = &__ts; |
41 | 41 | ||
42 | BUG_ON(pps == NULL); | ||
43 | |||
42 | /* Now do the PPS event report */ | 44 | /* Now do the PPS event report */ |
43 | pps_event(id, ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR, | 45 | pps_event(pps, ts, status ? PPS_CAPTUREASSERT : |
44 | NULL); | 46 | PPS_CAPTURECLEAR, NULL); |
45 | 47 | ||
46 | pr_debug("PPS %s at %lu on source #%d\n", | 48 | dev_dbg(pps->dev, "PPS %s at %lu\n", |
47 | status ? "assert" : "clear", jiffies, id); | 49 | status ? "assert" : "clear", jiffies); |
48 | } | 50 | } |
49 | 51 | ||
50 | static int (*alias_n_tty_open)(struct tty_struct *tty); | 52 | static int (*alias_n_tty_open)(struct tty_struct *tty); |
@@ -54,6 +56,7 @@ static int pps_tty_open(struct tty_struct *tty) | |||
54 | struct pps_source_info info; | 56 | struct pps_source_info info; |
55 | struct tty_driver *drv = tty->driver; | 57 | struct tty_driver *drv = tty->driver; |
56 | int index = tty->index + drv->name_base; | 58 | int index = tty->index + drv->name_base; |
59 | struct pps_device *pps; | ||
57 | int ret; | 60 | int ret; |
58 | 61 | ||
59 | info.owner = THIS_MODULE; | 62 | info.owner = THIS_MODULE; |
@@ -64,34 +67,42 @@ static int pps_tty_open(struct tty_struct *tty) | |||
64 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ | 67 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ |
65 | PPS_CANWAIT | PPS_TSFMT_TSPEC; | 68 | PPS_CANWAIT | PPS_TSFMT_TSPEC; |
66 | 69 | ||
67 | ret = pps_register_source(&info, PPS_CAPTUREBOTH | \ | 70 | pps = pps_register_source(&info, PPS_CAPTUREBOTH | \ |
68 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); | 71 | PPS_OFFSETASSERT | PPS_OFFSETCLEAR); |
69 | if (ret < 0) { | 72 | if (pps == NULL) { |
70 | pr_err("cannot register PPS source \"%s\"\n", info.path); | 73 | pr_err("cannot register PPS source \"%s\"\n", info.path); |
71 | return ret; | 74 | return -ENOMEM; |
72 | } | 75 | } |
73 | tty->disc_data = (void *)(long)ret; | 76 | tty->disc_data = pps; |
74 | 77 | ||
75 | /* Should open N_TTY ldisc too */ | 78 | /* Should open N_TTY ldisc too */ |
76 | ret = alias_n_tty_open(tty); | 79 | ret = alias_n_tty_open(tty); |
77 | if (ret < 0) | 80 | if (ret < 0) { |
78 | pps_unregister_source((long)tty->disc_data); | 81 | pr_err("cannot open tty ldisc \"%s\"\n", info.path); |
82 | goto err_unregister; | ||
83 | } | ||
79 | 84 | ||
80 | pr_info("PPS source #%d \"%s\" added\n", ret, info.path); | 85 | dev_info(pps->dev, "source \"%s\" added\n", info.path); |
81 | 86 | ||
82 | return 0; | 87 | return 0; |
88 | |||
89 | err_unregister: | ||
90 | tty->disc_data = NULL; | ||
91 | pps_unregister_source(pps); | ||
92 | return ret; | ||
83 | } | 93 | } |
84 | 94 | ||
85 | static void (*alias_n_tty_close)(struct tty_struct *tty); | 95 | static void (*alias_n_tty_close)(struct tty_struct *tty); |
86 | 96 | ||
87 | static void pps_tty_close(struct tty_struct *tty) | 97 | static void pps_tty_close(struct tty_struct *tty) |
88 | { | 98 | { |
89 | int id = (long)tty->disc_data; | 99 | struct pps_device *pps = (struct pps_device *)tty->disc_data; |
90 | 100 | ||
91 | pps_unregister_source(id); | ||
92 | alias_n_tty_close(tty); | 101 | alias_n_tty_close(tty); |
93 | 102 | ||
94 | pr_info("PPS source #%d removed\n", id); | 103 | tty->disc_data = NULL; |
104 | dev_info(pps->dev, "removed\n"); | ||
105 | pps_unregister_source(pps); | ||
95 | } | 106 | } |
96 | 107 | ||
97 | static struct tty_ldisc_ops pps_ldisc_ops; | 108 | static struct tty_ldisc_ops pps_ldisc_ops; |