fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / char / hvsi.c
index a952218..d780683 100644 (file)
@@ -69,7 +69,7 @@
 #define __ALIGNED__    __attribute__((__aligned__(sizeof(long))))
 
 struct hvsi_struct {
-       struct work_struct writer;
+       struct delayed_work writer;
        struct work_struct handshaker;
        wait_queue_head_t emptyq; /* woken when outbuf is emptied */
        wait_queue_head_t stateq; /* woken when HVSI state changes */
@@ -311,7 +311,8 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
                                /* CD went away; no more connection */
                                pr_debug("hvsi%i: CD dropped\n", hp->index);
                                hp->mctrl &= TIOCM_CD;
-                               if (!(hp->tty->flags & CLOCAL))
+                               /* If userland hasn't done an open(2) yet, hp->tty is NULL. */
+                               if (hp->tty && !(hp->tty->flags & CLOCAL))
                                        *to_hangup = hp->tty;
                        }
                        break;
@@ -405,7 +406,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
                        hp->sysrq = 1;
                        continue;
                } else if (hp->sysrq) {
-                       handle_sysrq(c, NULL, hp->tty);
+                       handle_sysrq(c, hp->tty);
                        hp->sysrq = 0;
                        continue;
                }
@@ -554,7 +555,7 @@ static void hvsi_send_overflow(struct hvsi_struct *hp)
  * must get all pending data because we only get an irq on empty->non-empty
  * transition
  */
-static irqreturn_t hvsi_interrupt(int irq, void *arg, struct pt_regs *regs)
+static irqreturn_t hvsi_interrupt(int irq, void *arg)
 {
        struct hvsi_struct *hp = (struct hvsi_struct *)arg;
        struct tty_struct *flip;
@@ -615,7 +616,7 @@ static int __init poll_for_state(struct hvsi_struct *hp, int state)
        unsigned long end_jiffies = jiffies + HVSI_TIMEOUT;
 
        for (;;) {
-               hvsi_interrupt(hp->virq, (void *)hp, NULL); /* get pending data */
+               hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */
 
                if (hp->state == state)
                        return 0;
@@ -743,9 +744,10 @@ static int hvsi_handshake(struct hvsi_struct *hp)
        return 0;
 }
 
-static void hvsi_handshaker(void *arg)
+static void hvsi_handshaker(struct work_struct *work)
 {
-       struct hvsi_struct *hp = (struct hvsi_struct *)arg;
+       struct hvsi_struct *hp =
+               container_of(work, struct hvsi_struct, handshaker);
 
        if (hvsi_handshake(hp) >= 0)
                return;
@@ -950,9 +952,10 @@ static void hvsi_push(struct hvsi_struct *hp)
 }
 
 /* hvsi_write_worker will keep rescheduling itself until outbuf is empty */
-static void hvsi_write_worker(void *arg)
+static void hvsi_write_worker(struct work_struct *work)
 {
-       struct hvsi_struct *hp = (struct hvsi_struct *)arg;
+       struct hvsi_struct *hp =
+               container_of(work, struct hvsi_struct, writer.work);
        unsigned long flags;
 #ifdef DEBUG
        static long start_j = 0;
@@ -986,10 +989,7 @@ static void hvsi_write_worker(void *arg)
                start_j = 0;
 #endif /* DEBUG */
                wake_up_all(&hp->emptyq);
-               if (test_bit(TTY_DO_WRITE_WAKEUP, &hp->tty->flags)
-                               && hp->tty->ldisc.write_wakeup)
-                       hp->tty->ldisc.write_wakeup(hp->tty);
-               wake_up_interruptible(&hp->tty->write_wait);
+               tty_wakeup(hp->tty);
        }
 
 out:
@@ -1132,7 +1132,7 @@ static int hvsi_tiocmset(struct tty_struct *tty, struct file *file,
 }
 
 
-static struct tty_operations hvsi_ops = {
+static const struct tty_operations hvsi_ops = {
        .open = hvsi_open,
        .close = hvsi_close,
        .write = hvsi_write,
@@ -1154,7 +1154,6 @@ static int __init hvsi_init(void)
                return -ENOMEM;
 
        hvsi_driver->owner = THIS_MODULE;
-       hvsi_driver->devfs_name = "hvsi/";
        hvsi_driver->driver_name = "hvsi";
        hvsi_driver->name = "hvsi";
        hvsi_driver->major = HVSI_MAJOR;
@@ -1162,6 +1161,8 @@ static int __init hvsi_init(void)
        hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM;
        hvsi_driver->init_termios = tty_std_termios;
        hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
+       hvsi_driver->init_termios.c_ispeed = 9600;
+       hvsi_driver->init_termios.c_ospeed = 9600;
        hvsi_driver->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(hvsi_driver, &hvsi_ops);
 
@@ -1169,7 +1170,7 @@ static int __init hvsi_init(void)
                struct hvsi_struct *hp = &hvsi_ports[i];
                int ret = 1;
 
-               ret = request_irq(hp->virq, hvsi_interrupt, SA_INTERRUPT, "hvsi", hp);
+               ret = request_irq(hp->virq, hvsi_interrupt, IRQF_DISABLED, "hvsi", hp);
                if (ret)
                        printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n",
                                hp->virq, ret);
@@ -1179,7 +1180,7 @@ static int __init hvsi_init(void)
        if (tty_register_driver(hvsi_driver))
                panic("Couldn't register hvsi console driver\n");
 
-       printk(KERN_INFO "HVSI: registered %i devices\n", hvsi_count);
+       printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count);
 
        return 0;
 }
@@ -1277,11 +1278,10 @@ static int __init hvsi_console_init(void)
                        vty != NULL;
                        vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) {
                struct hvsi_struct *hp;
-               uint32_t *vtermno;
-               uint32_t *irq;
+               const uint32_t *vtermno, *irq;
 
-               vtermno = (uint32_t *)get_property(vty, "reg", NULL);
-               irq = (uint32_t *)get_property(vty, "interrupts", NULL);
+               vtermno = get_property(vty, "reg", NULL);
+               irq = get_property(vty, "interrupts", NULL);
                if (!vtermno || !irq)
                        continue;
 
@@ -1291,8 +1291,8 @@ static int __init hvsi_console_init(void)
                }
 
                hp = &hvsi_ports[hvsi_count];
-               INIT_WORK(&hp->writer, hvsi_write_worker, hp);
-               INIT_WORK(&hp->handshaker, hvsi_handshaker, hp);
+               INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker);
+               INIT_WORK(&hp->handshaker, hvsi_handshaker);
                init_waitqueue_head(&hp->emptyq);
                init_waitqueue_head(&hp->stateq);
                spin_lock_init(&hp->lock);
@@ -1300,13 +1300,12 @@ static int __init hvsi_console_init(void)
                hp->inbuf_end = hp->inbuf;
                hp->state = HVSI_CLOSED;
                hp->vtermno = *vtermno;
-               hp->virq = virt_irq_create_mapping(irq[0]);
+               hp->virq = irq_create_mapping(NULL, irq[0]);
                if (hp->virq == NO_IRQ) {
                        printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
-                               __FUNCTION__, hp->virq);
+                               __FUNCTION__, irq[0]);
                        continue;
-               } else
-                       hp->virq = irq_offset_up(hp->virq);
+               }
 
                hvsi_count++;
        }