]> Pileus Git - ~andy/linux/blobdiff - arch/alpha/kernel/srmcons.c
Merge branch 'vm' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[~andy/linux] / arch / alpha / kernel / srmcons.c
index 75692320386080c25a730f1e78779b1851f75926..3ea809430eda0f3ea018df2b540a75614846ce05 100644 (file)
@@ -30,10 +30,9 @@ static int srm_is_registered_console = 0;
 #define MAX_SRM_CONSOLE_DEVICES 1      /* only support 1 console device */
 
 struct srmcons_private {
-       struct tty_struct *tty;
+       struct tty_port port;
        struct timer_list timer;
-       spinlock_t lock;
-};
+} srmcons_singleton;
 
 typedef union _srmcons_result {
        struct {
@@ -68,22 +67,21 @@ static void
 srmcons_receive_chars(unsigned long data)
 {
        struct srmcons_private *srmconsp = (struct srmcons_private *)data;
+       struct tty_port *port = &srmconsp->port;
        unsigned long flags;
        int incr = 10;
 
        local_irq_save(flags);
        if (spin_trylock(&srmcons_callback_lock)) {
-               if (!srmcons_do_receive_chars(srmconsp->tty))
+               if (!srmcons_do_receive_chars(port->tty))
                        incr = 100;
                spin_unlock(&srmcons_callback_lock);
        } 
 
-       spin_lock(&srmconsp->lock);
-       if (srmconsp->tty) {
-               srmconsp->timer.expires = jiffies + incr;
-               add_timer(&srmconsp->timer);
-       }
-       spin_unlock(&srmconsp->lock);
+       spin_lock(&port->lock);
+       if (port->tty)
+               mod_timer(&srmconsp->timer, jiffies + incr);
+       spin_unlock(&port->lock);
 
        local_irq_restore(flags);
 }
@@ -155,57 +153,23 @@ srmcons_chars_in_buffer(struct tty_struct *tty)
        return 0;
 }
 
-static int
-srmcons_get_private_struct(struct srmcons_private **ps)
-{
-       static struct srmcons_private *srmconsp = NULL;
-       static DEFINE_SPINLOCK(srmconsp_lock);
-       unsigned long flags;
-       int retval = 0;
-
-       if (srmconsp == NULL) {
-               spin_lock_irqsave(&srmconsp_lock, flags);
-
-               srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
-               if (srmconsp == NULL)
-                       retval = -ENOMEM;
-               else {
-                       srmconsp->tty = NULL;
-                       spin_lock_init(&srmconsp->lock);
-                       init_timer(&srmconsp->timer);
-               }
-
-               spin_unlock_irqrestore(&srmconsp_lock, flags);
-       }
-
-       *ps = srmconsp;
-       return retval;
-}
-
 static int
 srmcons_open(struct tty_struct *tty, struct file *filp)
 {
-       struct srmcons_private *srmconsp;
+       struct srmcons_private *srmconsp = &srmcons_singleton;
+       struct tty_port *port = &srmconsp->port;
        unsigned long flags;
-       int retval;
-
-       retval = srmcons_get_private_struct(&srmconsp);
-       if (retval)
-               return retval;
 
-       spin_lock_irqsave(&srmconsp->lock, flags);
+       spin_lock_irqsave(&port->lock, flags);
 
-       if (!srmconsp->tty) {
+       if (!port->tty) {
                tty->driver_data = srmconsp;
-
-               srmconsp->tty = tty;
-               srmconsp->timer.function = srmcons_receive_chars;
-               srmconsp->timer.data = (unsigned long)srmconsp;
-               srmconsp->timer.expires = jiffies + 10;
-               add_timer(&srmconsp->timer);
+               tty->port = port;
+               port->tty = tty; /* XXX proper refcounting */
+               mod_timer(&srmconsp->timer, jiffies + 10);
        }
 
-       spin_unlock_irqrestore(&srmconsp->lock, flags);
+       spin_unlock_irqrestore(&port->lock, flags);
 
        return 0;
 }
@@ -214,16 +178,17 @@ static void
 srmcons_close(struct tty_struct *tty, struct file *filp)
 {
        struct srmcons_private *srmconsp = tty->driver_data;
+       struct tty_port *port = &srmconsp->port;
        unsigned long flags;
 
-       spin_lock_irqsave(&srmconsp->lock, flags);
+       spin_lock_irqsave(&port->lock, flags);
 
        if (tty->count == 1) {
-               srmconsp->tty = NULL;
+               port->tty = NULL;
                del_timer(&srmconsp->timer);
        }
 
-       spin_unlock_irqrestore(&srmconsp->lock, flags);
+       spin_unlock_irqrestore(&port->lock, flags);
 }
 
 
@@ -240,6 +205,9 @@ static const struct tty_operations srmcons_ops = {
 static int __init
 srmcons_init(void)
 {
+       tty_port_init(&srmcons_singleton.port);
+       setup_timer(&srmcons_singleton.timer, srmcons_receive_chars,
+                       (unsigned long)&srmcons_singleton);
        if (srm_is_registered_console) {
                struct tty_driver *driver;
                int err;
@@ -289,7 +257,7 @@ srm_console_device(struct console *co, int *index)
        return srmcons_driver;
 }
 
-static int __init
+static int
 srm_console_setup(struct console *co, char *options)
 {
        return 0;
@@ -300,7 +268,7 @@ static struct console srmcons = {
        .write          = srm_console_write,
        .device         = srm_console_device,
        .setup          = srm_console_setup,
-       .flags          = CON_PRINTBUFFER,
+       .flags          = CON_PRINTBUFFER | CON_BOOT,
        .index          = -1,
 };