*               tasklist_lock to walk task list for hangup event
  *                 ->siglock to protect ->signal/->sighand
  */
-static void do_tty_hangup(struct work_struct *work)
+void tty_vhangup_locked(struct tty_struct *tty)
 {
-       struct tty_struct *tty =
-               container_of(work, struct tty_struct, hangup_work);
        struct file *cons_filp = NULL;
        struct file *filp, *f = NULL;
        struct task_struct *p;
        /* inuse_filps is protected by the single tty lock,
           this really needs to change if we want to flush the
           workqueue with the lock held */
-       tty_lock_nested(); /* called with BTM held from pty_close and
-                               others */
        check_tty_count(tty, "do_tty_hangup");
 
        file_list_lock();
         */
        set_bit(TTY_HUPPED, &tty->flags);
        tty_ldisc_enable(tty);
-       tty_unlock();
        if (f)
                fput(f);
 }
 
+static void do_tty_hangup(struct work_struct *work)
+{
+       struct tty_struct *tty =
+               container_of(work, struct tty_struct, hangup_work);
+
+       tty_lock();
+       tty_vhangup_locked(tty);
+       tty_unlock();
+}
+
 /**
  *     tty_hangup              -       trigger a hangup event
  *     @tty: tty to hangup
 
        printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf));
 #endif
-       do_tty_hangup(&tty->hangup_work);
+       tty_lock();
+       tty_vhangup_locked(tty);
+       tty_unlock();
 }
 
 EXPORT_SYMBOL(tty_vhangup);
        tty = get_current_tty();
        if (tty) {
                tty_pgrp = get_pid(tty->pgrp);
-               tty_lock_nested(); /* see above */
-               if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
-                       tty_vhangup(tty);
-               tty_unlock();
+               if (on_exit) {
+                       tty_lock();
+                       if (tty->driver->type != TTY_DRIVER_TYPE_PTY)
+                               tty_vhangup_locked(tty);
+                       tty_unlock();
+               }
                tty_kref_put(tty);
        } else if (on_exit) {
                struct pid *old_pgrp;
        int ret;
 
        if (driver->ops->install) {
-               tty_lock_nested(); /* already called with BTM held */
                ret = driver->ops->install(driver, tty);
-               tty_unlock();
                return ret;
        }
 
        if (tty_init_termios(tty) == 0) {
-               tty_lock_nested();
                tty_driver_kref_get(driver);
                tty->count++;
                driver->ttys[idx] = tty;
-               tty_unlock();
                return 0;
        }
        return -ENOMEM;
        struct tty_struct *tty;
        int retval;
 
-       tty_lock_nested(); /* always called with tty lock held already */
-
        /* Check if pty master is being opened multiple times */
        if (driver->subtype == PTY_TYPE_MASTER &&
                (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
-               tty_unlock();
                return ERR_PTR(-EIO);
        }
-       tty_unlock();
 
        /*
         * First time open is complex, especially for PTY devices.
        if (printk_ratelimit())
                printk(KERN_INFO "tty_init_dev: ldisc open failed, "
                                 "clearing slot %d\n", idx);
-       tty_lock_nested();
        release_tty(tty, idx);
-       tty_unlock();
        return ERR_PTR(retval);
 }
 
 
 extern int tty_signal(int sig, struct tty_struct *tty);
 extern void tty_hangup(struct tty_struct *tty);
 extern void tty_vhangup(struct tty_struct *tty);
+extern void tty_vhangup_locked(struct tty_struct *tty);
 extern void tty_vhangup_self(void);
 extern void tty_unhangup(struct file *filp);
 extern int tty_hung_up_p(struct file *filp);
                     unsigned int cmd, unsigned long arg);
 
 /* functions for preparation of BKL removal */
-
-/*
- * tty_lock_nested get the tty_lock while potentially holding it
- *
- * The Big TTY Mutex is a recursive lock, meaning you can take it
- * from a thread that is already holding it.
- * This is bad for a number of reasons, so tty_lock_nested should
- * really be used as rarely as possible. If a code location can
- * be shown to never get called with this held already, it should
- * use tty_lock() instead.
- */
-static inline void __lockfunc tty_lock_nested(void) __acquires(kernel_lock)
-{
-       lock_kernel();
-}
 static inline void tty_lock(void) __acquires(kernel_lock)
 {
 #ifdef CONFIG_LOCK_KERNEL