summaryrefslogtreecommitdiff
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-20 15:55:17 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-20 15:55:17 -0700
commite11c675ede0d42a405ae595528bf0b29ce1ae56f (patch)
treee0ec481e66e4a4b70289d78992b209639a582c0c /drivers/char/tty_io.c
parent467f9957d9283be40101d7255d06fae7e211ff4c (diff)
parent7bd032dc2793afcbaf4a350056768da84cdbd89b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (79 commits) USB serial: update the console driver usb-serial: straighten out serial_open usb-serial: add missing tests and debug lines usb-serial: rename subroutines usb-serial: fix termios initialization logic usb-serial: acquire references when a new tty is installed usb-serial: change logic of serial lookups usb-serial: put subroutines in logical order usb-serial: change referencing of port and serial structures tty: Char: mxser, use THRE for ASPP_OQUEUE ioctl tty: Char: mxser, add support for CP112UL uartlite: support shared interrupt lines tty: USB: serial/mct_u232, fix tty refcnt tty: riscom8, fix tty refcnt tty: riscom8, fix shutdown declaration TTY: fix typos tty: Power: fix suspend vt regression tty: vt: use printk_once tty: handle VT specific compat ioctls in vt driver n_tty: move echoctl check and clean up logic ...
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index a3afa0c387cd..05f443c47bbe 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1184,6 +1184,7 @@ int tty_init_termios(struct tty_struct *tty)
tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
return 0;
}
+EXPORT_SYMBOL_GPL(tty_init_termios);
/**
* tty_driver_install_tty() - install a tty entry in the driver
@@ -1386,10 +1387,14 @@ EXPORT_SYMBOL(tty_shutdown);
* tty_mutex - sometimes only
* takes the file list lock internally when working on the list
* of ttys that the driver keeps.
+ *
+ * This method gets called from a work queue so that the driver private
+ * shutdown ops can sleep (needed for USB at least)
*/
-static void release_one_tty(struct kref *kref)
+static void release_one_tty(struct work_struct *work)
{
- struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
+ struct tty_struct *tty =
+ container_of(work, struct tty_struct, hangup_work);
struct tty_driver *driver = tty->driver;
if (tty->ops->shutdown)
@@ -1407,6 +1412,15 @@ static void release_one_tty(struct kref *kref)
free_tty_struct(tty);
}
+static void queue_release_one_tty(struct kref *kref)
+{
+ struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
+ /* The hangup queue is now free so we can reuse it rather than
+ waste a chunk of memory for each port */
+ INIT_WORK(&tty->hangup_work, release_one_tty);
+ schedule_work(&tty->hangup_work);
+}
+
/**
* tty_kref_put - release a tty kref
* @tty: tty device
@@ -1418,7 +1432,7 @@ static void release_one_tty(struct kref *kref)
void tty_kref_put(struct tty_struct *tty)
{
if (tty)
- kref_put(&tty->kref, release_one_tty);
+ kref_put(&tty->kref, queue_release_one_tty);
}
EXPORT_SYMBOL(tty_kref_put);
@@ -2085,7 +2099,7 @@ static int tioccons(struct file *file)
* the generic functionality existed. This piece of history is preserved
* in the expected tty API of posix OS's.
*
- * Locking: none, the open fle handle ensures it won't go away.
+ * Locking: none, the open file handle ensures it won't go away.
*/
static int fionbio(struct file *file, int __user *p)