spin_lock_irqsave(&hp->lock, flags);
        /* Check and then increment for fast path open. */
        if (hp->count++ > 0) {
+               tty_kref_get(tty);
                spin_unlock_irqrestore(&hp->lock, flags);
                hvc_kick();
                return 0;
 
        tty->driver_data = hp;
 
-       hp->tty = tty;
+       hp->tty = tty_kref_get(tty);
 
        spin_unlock_irqrestore(&hp->lock, flags);
 
                spin_lock_irqsave(&hp->lock, flags);
                hp->tty = NULL;
                spin_unlock_irqrestore(&hp->lock, flags);
+               tty_kref_put(tty);
                tty->driver_data = NULL;
                kref_put(&hp->kref, destroy_hvc_struct);
                printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
                return;
 
        hp = tty->driver_data;
+
        spin_lock_irqsave(&hp->lock, flags);
+       tty_kref_get(tty);
 
        if (--hp->count == 0) {
                /* We are done with the tty pointer now. */
                hp->tty = NULL;
                spin_unlock_irqrestore(&hp->lock, flags);
 
+               /* Put the ref obtained in hvc_open() */
+               tty_kref_put(tty);
+
                if (hp->ops->notifier_del)
                        hp->ops->notifier_del(hp, hp->data);
 
                spin_unlock_irqrestore(&hp->lock, flags);
        }
 
+       tty_kref_put(tty);
        kref_put(&hp->kref, destroy_hvc_struct);
 }
 
        spin_unlock_irqrestore(&hp->lock, flags);
 
        if (hp->ops->notifier_hangup)
-                       hp->ops->notifier_hangup(hp, hp->data);
+               hp->ops->notifier_hangup(hp, hp->data);
 
        while(temp_open_count) {
                --temp_open_count;
+               tty_kref_put(tty);
                kref_put(&hp->kref, destroy_hvc_struct);
        }
 }
        }
 
        /* No tty attached, just skip */
-       tty = hp->tty;
+       tty = tty_kref_get(hp->tty);
        if (tty == NULL)
                goto bail;
 
 
                tty_flip_buffer_push(tty);
        }
+       if (tty)
+               tty_kref_put(tty);
 
        return poll_mask;
 }
        struct tty_struct *tty;
 
        spin_lock_irqsave(&hp->lock, flags);
-       tty = hp->tty;
+       tty = tty_kref_get(hp->tty);
 
        if (hp->index < MAX_NR_HVC_CONSOLES)
                vtermnos[hp->index] = -1;
        /*
         * We 'put' the instance that was grabbed when the kref instance
         * was initialized using kref_init().  Let the last holder of this
-        * kref cause it to be removed, which will probably be the tty_hangup
+        * kref cause it to be removed, which will probably be the tty_vhangup
         * below.
         */
        kref_put(&hp->kref, destroy_hvc_struct);
 
        /*
-        * This function call will auto chain call hvc_hangup.  The tty should
-        * always be valid at this time unless a simultaneous tty close already
-        * cleaned up the hvc_struct.
+        * This function call will auto chain call hvc_hangup.
         */
-       if (tty)
-               tty_hangup(tty);
+       if (tty) {
+               tty_vhangup(tty);
+               tty_kref_put(tty);
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(hvc_remove);