TTY: hvc_console, add tty install
authorJiri Slaby <jslaby@suse.cz>
Tue, 7 Aug 2012 19:48:04 +0000 (21:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Aug 2012 23:53:14 +0000 (16:53 -0700)
This has two outcomes:
* we give the TTY layer a tty_port
* we do not find the info structure every time open is called on that
  tty

Since we take a reference to a port in ->install, we need also
->cleanup to drop that reference.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/hvc/hvc_console.c

index 2d691eb7c40aa28f30602834902cc48fc1c52dad..7f80f15681cd3fa6fe743c01def27bb63ec59bff 100644 (file)
@@ -299,20 +299,33 @@ static void hvc_unthrottle(struct tty_struct *tty)
        hvc_kick();
 }
 
+static int hvc_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+       struct hvc_struct *hp;
+       int rc;
+
+       /* Auto increments kref reference if found. */
+       if (!(hp = hvc_get_by_index(tty->index)))
+               return -ENODEV;
+
+       tty->driver_data = hp;
+
+       rc = tty_port_install(&hp->port, driver, tty);
+       if (rc)
+               tty_port_put(&hp->port);
+       return rc;
+}
+
 /*
  * The TTY interface won't be used until after the vio layer has exposed the vty
  * adapter to the kernel.
  */
 static int hvc_open(struct tty_struct *tty, struct file * filp)
 {
-       struct hvc_struct *hp;
+       struct hvc_struct *hp = tty->driver_data;
        unsigned long flags;
        int rc = 0;
 
-       /* Auto increments kref reference if found. */
-       if (!(hp = hvc_get_by_index(tty->index)))
-               return -ENODEV;
-
        spin_lock_irqsave(&hp->port.lock, flags);
        /* Check and then increment for fast path open. */
        if (hp->port.count++ > 0) {
@@ -322,7 +335,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
        } /* else count == 0 */
        spin_unlock_irqrestore(&hp->port.lock, flags);
 
-       tty->driver_data = hp;
        tty_port_tty_set(&hp->port, tty);
 
        if (hp->ops->notifier_add)
@@ -389,6 +401,11 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
                                hp->vtermno, hp->port.count);
                spin_unlock_irqrestore(&hp->port.lock, flags);
        }
+}
+
+static void hvc_cleanup(struct tty_struct *tty)
+{
+       struct hvc_struct *hp = tty->driver_data;
 
        tty_port_put(&hp->port);
 }
@@ -792,8 +809,10 @@ static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch)
 #endif
 
 static const struct tty_operations hvc_ops = {
+       .install = hvc_install,
        .open = hvc_open,
        .close = hvc_close,
+       .cleanup = hvc_cleanup,
        .write = hvc_write,
        .hangup = hvc_hangup,
        .unthrottle = hvc_unthrottle,