summaryrefslogtreecommitdiff
path: root/drivers/tty/tty_io.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 11:38:36 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 11:38:36 -0700
commit2f01ea908bcf838e815c0124b579513dbda3b8c8 (patch)
treef42db47c1695daaf369f08a21b2267d4a8ece756 /drivers/tty/tty_io.c
parent751144271f4b63d5de9005ea4e5e6e5c7c6fd629 (diff)
parent2d1d3f3ae985ec5676fb56ff2c7acad2e1c4e6eb (diff)
Merge tag 'tty-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver patches from Greg KH: "Here's the big tty/serial driver pull request for 3.12-rc1. Lots of n_tty reworks to resolve some very long-standing issues, removing the 3-4 different locks that were taken for every character. This code has been beaten on for a long time in linux-next with no reported regressions. Other than that, a range of serial and tty driver updates and revisions. Full details in the shortlog" * tag 'tty-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (226 commits) hvc_xen: Remove unnecessary __GFP_ZERO from kzalloc serial: imx: initialize the local variable tty: ar933x_uart: add device tree support and binding documentation tty: ar933x_uart: allow to build the driver as a module ARM: dts: msm: Update uartdm compatible strings devicetree: serial: Document msm_serial bindings serial: unify serial bindings into a single dir serial: fsl-imx-uart: Cleanup duplicate device tree binding tty: ar933x_uart: use config_enabled() macro to clean up ifdefs tty: ar933x_uart: remove superfluous assignment of ar933x_uart_driver.nr tty: ar933x_uart: use the clk API to get the uart clock tty: serial: cpm_uart: Adding proper request of GPIO used by cpm_uart driver serial: sirf: fix the amount of serial ports serial: sirf: define macro for some magic numbers of USP serial: icom: move array overflow checks earlier TTY: amiserial, remove unnecessary platform_set_drvdata() serial: st-asc: remove unnecessary platform_set_drvdata() msm_serial: Send more than 1 character on the console w/ UARTDM msm_serial: Add support for non-GSBI UARTDM devices msm_serial: Switch clock consumer strings and simplify code ...
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r--drivers/tty/tty_io.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 366af832794b..a9355ce1c6d5 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -603,8 +603,8 @@ static int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
* BTM
* redirect lock for undoing redirection
* file list lock for manipulating list of ttys
- * tty_ldisc_lock from called functions
- * termios_mutex resetting termios data
+ * tty_ldiscs_lock from called functions
+ * termios_rwsem resetting termios data
* tasklist_lock to walk task list for hangup event
* ->siglock to protect ->signal/->sighand
*/
@@ -629,6 +629,11 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
tty_lock(tty);
+ if (test_bit(TTY_HUPPED, &tty->flags)) {
+ tty_unlock(tty);
+ return;
+ }
+
/* some functions below drop BTM, so we need this bit */
set_bit(TTY_HUPPING, &tty->flags);
@@ -664,7 +669,6 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session)
spin_lock_irq(&tty->ctrl_lock);
clear_bit(TTY_THROTTLED, &tty->flags);
- clear_bit(TTY_PUSH, &tty->flags);
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
put_pid(tty->session);
put_pid(tty->pgrp);
@@ -1388,8 +1392,7 @@ static int tty_reopen(struct tty_struct *tty)
struct tty_driver *driver = tty->driver;
if (test_bit(TTY_CLOSING, &tty->flags) ||
- test_bit(TTY_HUPPING, &tty->flags) ||
- test_bit(TTY_LDISC_CHANGING, &tty->flags))
+ test_bit(TTY_HUPPING, &tty->flags))
return -EIO;
if (driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -1405,7 +1408,7 @@ static int tty_reopen(struct tty_struct *tty)
}
tty->count++;
- WARN_ON(!test_bit(TTY_LDISC, &tty->flags));
+ WARN_ON(!tty->ldisc);
return 0;
}
@@ -2202,7 +2205,7 @@ static int tty_fasync(int fd, struct file *filp, int on)
* FIXME: does not honour flow control ??
*
* Locking:
- * Called functions take tty_ldisc_lock
+ * Called functions take tty_ldiscs_lock
* current->signal->tty check is safe without locks
*
* FIXME: may race normal receive processing
@@ -2231,7 +2234,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
*
* Copies the kernel idea of the window size into the user buffer.
*
- * Locking: tty->termios_mutex is taken to ensure the winsize data
+ * Locking: tty->winsize_mutex is taken to ensure the winsize data
* is consistent.
*/
@@ -2239,9 +2242,9 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
{
int err;
- mutex_lock(&tty->termios_mutex);
+ mutex_lock(&tty->winsize_mutex);
err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
- mutex_unlock(&tty->termios_mutex);
+ mutex_unlock(&tty->winsize_mutex);
return err ? -EFAULT: 0;
}
@@ -2262,7 +2265,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
unsigned long flags;
/* Lock the tty */
- mutex_lock(&tty->termios_mutex);
+ mutex_lock(&tty->winsize_mutex);
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
goto done;
/* Get the PID values and reference them so we can
@@ -2277,7 +2280,7 @@ int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
tty->winsize = *ws;
done:
- mutex_unlock(&tty->termios_mutex);
+ mutex_unlock(&tty->winsize_mutex);
return 0;
}
EXPORT_SYMBOL(tty_do_resize);
@@ -3016,8 +3019,10 @@ void initialize_tty_struct(struct tty_struct *tty,
tty->session = NULL;
tty->pgrp = NULL;
mutex_init(&tty->legacy_mutex);
- mutex_init(&tty->termios_mutex);
- mutex_init(&tty->ldisc_mutex);
+ mutex_init(&tty->throttle_mutex);
+ init_rwsem(&tty->termios_rwsem);
+ mutex_init(&tty->winsize_mutex);
+ init_ldsem(&tty->ldisc_sem);
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
INIT_WORK(&tty->hangup_work, do_tty_hangup);