diff options
Diffstat (limited to 'drivers/tty/tty_mutex.c')
| -rw-r--r-- | drivers/tty/tty_mutex.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c new file mode 100644 index 00000000000..2e41abebbcb --- /dev/null +++ b/drivers/tty/tty_mutex.c @@ -0,0 +1,73 @@ +#include <linux/tty.h> +#include <linux/module.h> +#include <linux/kallsyms.h> +#include <linux/semaphore.h> +#include <linux/sched.h> + +/* Legacy tty mutex glue */ + +enum { + TTY_MUTEX_NORMAL, + TTY_MUTEX_NESTED, +}; + +/* + * Getting the big tty mutex. + */ + +static void __lockfunc tty_lock_nested(struct tty_struct *tty, + unsigned int subclass) +{ + if (tty->magic != TTY_MAGIC) { + pr_err("L Bad %p\n", tty); + WARN_ON(1); + return; + } + tty_kref_get(tty); + mutex_lock_nested(&tty->legacy_mutex, subclass); +} + +void __lockfunc tty_lock(struct tty_struct *tty) +{ + return tty_lock_nested(tty, TTY_MUTEX_NORMAL); +} +EXPORT_SYMBOL(tty_lock); + +void __lockfunc tty_unlock(struct tty_struct *tty) +{ + if (tty->magic != TTY_MAGIC) { + pr_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_nested(tty2, TTY_MUTEX_NESTED); + } else { + if (tty2 && tty2 != tty) + tty_lock(tty2); + tty_lock_nested(tty, TTY_MUTEX_NESTED); + } +} +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); |
