summaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_mutex.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 01:12:24 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 01:12:24 +0200
commit94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch)
tree39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers/tty/tty_mutex.c
parentMerge tag 'driver-core-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/... (diff)
parentserial: bfin_uart: Make MMR access compatible with 32 bits bf609 style contro... (diff)
downloadlinux-94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9.tar.xz
linux-94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9.zip
Merge tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY updates from Greg Kroah-Hartman: "Here's the big TTY/serial driver pull request for the 3.5-rc1 merge window. Nothing major in here, just lots of incremental changes from Alan and Jiri reworking some tty core things to behave better and to get a more solid grasp on some of the nasty tty locking issues. There are a few tty and serial driver updates in here as well. All of this has been in the linux-next releases for a while with no problems. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (115 commits) serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller. serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width. serial: bfin_uart: narrow the reboot condition in DMA tx interrupt serial: bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller. Revert "serial_core: Update buffer overrun statistics." tty: hvc_xen: NULL dereference on allocation failure tty: Fix LED error return tty: Allow uart_register/unregister/register tty: move global ldisc idle waitqueue to the individual ldisc serial8250-em: Add DT support serial8250-em: clk_get() IS_ERR() error handling fix serial_core: Update buffer overrun statistics. tty: drop the pty lock during hangup cris: fix missing tty arg in wait_event_interruptible_tty call tty/amiserial: Add missing argument for tty_unlock() tty_lock: Localise the lock pty: Lock the devpts bits privately tty_lock: undo the old tty_lock use on the ctty serial8250-em: Emma Mobile UART driver V2 Add missing call to uart_update_timeout() ...
Diffstat (limited to 'drivers/tty/tty_mutex.c')
-rw-r--r--drivers/tty/tty_mutex.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c
index 9ff986c32a21..69adc80c98cd 100644
--- a/drivers/tty/tty_mutex.c
+++ b/drivers/tty/tty_mutex.c
@@ -4,29 +4,59 @@
#include <linux/semaphore.h>
#include <linux/sched.h>
-/*
- * The 'big tty mutex'
- *
- * This mutex is taken and released by tty_lock() and tty_unlock(),
- * replacing the older big kernel lock.
- * It can no longer be taken recursively, and does not get
- * released implicitly while sleeping.
- *
- * Don't use in new code.
- */
-static DEFINE_MUTEX(big_tty_mutex);
+/* Legacy tty mutex glue */
/*
* Getting the big tty mutex.
*/
-void __lockfunc tty_lock(void)
+
+void __lockfunc tty_lock(struct tty_struct *tty)
{
- mutex_lock(&big_tty_mutex);
+ if (tty->magic != TTY_MAGIC) {
+ printk(KERN_ERR "L Bad %p\n", tty);
+ WARN_ON(1);
+ return;
+ }
+ tty_kref_get(tty);
+ mutex_lock(&tty->legacy_mutex);
}
EXPORT_SYMBOL(tty_lock);
-void __lockfunc tty_unlock(void)
+void __lockfunc tty_unlock(struct tty_struct *tty)
{
- mutex_unlock(&big_tty_mutex);
+ if (tty->magic != TTY_MAGIC) {
+ printk(KERN_ERR "U Bad %p\n", tty);
+ WARN_ON(1);
+ return;
+ }
+ mutex_unlock(&tty->legacy_mutex);
+ tty_kref_put(tty);
}
EXPORT_SYMBOL(tty_unlock);
+
+/*
+ * Getting the big tty mutex for a pair of ttys with lock ordering
+ * On a non pty/tty pair tty2 can be NULL which is just fine.
+ */
+void __lockfunc tty_lock_pair(struct tty_struct *tty,
+ struct tty_struct *tty2)
+{
+ if (tty < tty2) {
+ tty_lock(tty);
+ tty_lock(tty2);
+ } else {
+ if (tty2 && tty2 != tty)
+ tty_lock(tty2);
+ tty_lock(tty);
+ }
+}
+EXPORT_SYMBOL(tty_lock_pair);
+
+void __lockfunc tty_unlock_pair(struct tty_struct *tty,
+ struct tty_struct *tty2)
+{
+ tty_unlock(tty);
+ if (tty2 && tty2 != tty)
+ tty_unlock(tty2);
+}
+EXPORT_SYMBOL(tty_unlock_pair);