aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:39:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commit4a90f09b20f4622dcbff1f0e1e6bae1704f8ad8c (patch)
tree9b275f88f2705cb10121d5982741aef3a088a7c8 /drivers/char
parent95f9bfc6b76e862265a2d70ae061eec18fe14140 (diff)
tty: usb-serial krefs
Use kref in the USB serial drivers so that we don't free tty structures from under the URB receive handlers as has historically been the case if you were unlucky. This also gives us a framework for general tty drivers to use tty_port objects and refcount. Contains two err->dev_err changes merged together to fix clashes in the -next tree. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tty_port.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 6fadb19d630..553b0e9d8d1 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -23,6 +23,7 @@ void tty_port_init(struct tty_port *port)
23 init_waitqueue_head(&port->open_wait); 23 init_waitqueue_head(&port->open_wait);
24 init_waitqueue_head(&port->close_wait); 24 init_waitqueue_head(&port->close_wait);
25 mutex_init(&port->mutex); 25 mutex_init(&port->mutex);
26 spin_lock_init(&port->lock);
26 port->close_delay = (50 * HZ) / 100; 27 port->close_delay = (50 * HZ) / 100;
27 port->closing_wait = (3000 * HZ) / 100; 28 port->closing_wait = (3000 * HZ) / 100;
28} 29}
@@ -53,3 +54,43 @@ void tty_port_free_xmit_buf(struct tty_port *port)
53EXPORT_SYMBOL(tty_port_free_xmit_buf); 54EXPORT_SYMBOL(tty_port_free_xmit_buf);
54 55
55 56
57/**
58 * tty_port_tty_get - get a tty reference
59 * @port: tty port
60 *
61 * Return a refcount protected tty instance or NULL if the port is not
62 * associated with a tty (eg due to close or hangup)
63 */
64
65struct tty_struct *tty_port_tty_get(struct tty_port *port)
66{
67 unsigned long flags;
68 struct tty_struct *tty;
69
70 spin_lock_irqsave(&port->lock, flags);
71 tty = tty_kref_get(port->tty);
72 spin_unlock_irqrestore(&port->lock, flags);
73 return tty;
74}
75EXPORT_SYMBOL(tty_port_tty_get);
76
77/**
78 * tty_port_tty_set - set the tty of a port
79 * @port: tty port
80 * @tty: the tty
81 *
82 * Associate the port and tty pair. Manages any internal refcounts.
83 * Pass NULL to deassociate a port
84 */
85
86void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
87{
88 unsigned long flags;
89
90 spin_lock_irqsave(&port->lock, flags);
91 if (port->tty)
92 tty_kref_put(port->tty);
93 port->tty = tty;
94 spin_unlock_irqrestore(&port->lock, flags);
95}
96EXPORT_SYMBOL(tty_port_tty_set);