aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_port.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:46:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:40 -0500
commita6614999e800cf3a134ce93ea46ef837e3c0e76e (patch)
tree56b0a29ed004a284561a4c3ff3ee52075acabb65 /drivers/char/tty_port.c
parent7834909f1eb96ba7c49ca2b9e3a69b500a2cff76 (diff)
tty: Introduce some close helpers for ports
Again this is a lot of common code we can unify Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_port.c')
-rw-r--r--drivers/char/tty_port.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 0723664fe0ab..b3175f54fe05 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -257,3 +257,61 @@ int tty_port_block_til_ready(struct tty_port *port,
257} 257}
258EXPORT_SYMBOL(tty_port_block_til_ready); 258EXPORT_SYMBOL(tty_port_block_til_ready);
259 259
260int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct file *filp)
261{
262 unsigned long flags;
263
264 spin_lock_irqsave(&port->lock, flags);
265 if (tty_hung_up_p(filp)) {
266 spin_unlock_irqrestore(&port->lock, flags);
267 return 0;
268 }
269
270 if( tty->count == 1 && port->count != 1) {
271 printk(KERN_WARNING
272 "tty_port_close_start: tty->count = 1 port count = %d.\n",
273 port->count);
274 port->count = 1;
275 }
276 if (--port->count < 0) {
277 printk(KERN_WARNING "tty_port_close_start: count = %d\n",
278 port->count);
279 port->count = 0;
280 }
281
282 if (port->count) {
283 spin_unlock_irqrestore(&port->lock, flags);
284 return 0;
285 }
286 port->flags |= ASYNC_CLOSING;
287 tty->closing = 1;
288 spin_unlock_irqrestore(&port->lock, flags);
289 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
290 tty_wait_until_sent(tty, port->closing_wait);
291 return 1;
292}
293EXPORT_SYMBOL(tty_port_close_start);
294
295void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
296{
297 unsigned long flags;
298
299 tty_ldisc_flush(tty);
300
301 spin_lock_irqsave(&port->lock, flags);
302 tty->closing = 0;
303
304 if (port->blocked_open) {
305 spin_unlock_irqrestore(&port->lock, flags);
306 if (port->close_delay) {
307 msleep_interruptible(
308 jiffies_to_msecs(port->close_delay));
309 }
310 spin_lock_irqsave(&port->lock, flags);
311 wake_up_interruptible(&port->open_wait);
312 }
313 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
314 wake_up_interruptible(&port->close_wait);
315 spin_unlock_irqrestore(&port->lock, flags);
316}
317EXPORT_SYMBOL(tty_port_close_end);