Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / serial / sunsu.c
index 79b1368..170d3d6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.55 2002/01/08 16:00:16 davem Exp $
+/*
  * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
 #include <linux/serial_reg.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/prom.h>
-#include <asm/of_device.h>
 
 #if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
@@ -311,7 +311,7 @@ static void sunsu_enable_ms(struct uart_port *port)
 static struct tty_struct *
 receive_chars(struct uart_sunsu_port *up, unsigned char *status)
 {
-       struct tty_struct *tty = up->port.info->tty;
+       struct tty_struct *tty = up->port.state->port.tty;
        unsigned char ch, flag;
        int max_count = 256;
        int saw_console_brk = 0;
@@ -389,7 +389,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status)
 
 static void transmit_chars(struct uart_sunsu_port *up)
 {
-       struct circ_buf *xmit = &up->port.info->xmit;
+       struct circ_buf *xmit = &up->port.state->xmit;
        int count;
 
        if (up->port.x_char) {
@@ -441,7 +441,7 @@ static void check_modem_status(struct uart_sunsu_port *up)
        if (status & UART_MSR_DCTS)
                uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
 
-       wake_up_interruptible(&up->port.info->delta_msr_wait);
+       wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 }
 
 static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id)
@@ -1173,12 +1173,12 @@ out:
 
 static struct uart_driver sunsu_reg = {
        .owner                  = THIS_MODULE,
-       .driver_name            = "serial",
+       .driver_name            = "sunsu",
        .dev_name               = "ttyS",
        .major                  = TTY_MAJOR,
 };
 
-static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
+static int __devinit sunsu_kbd_ms_init(struct uart_sunsu_port *up)
 {
        int quot, baud;
 #ifdef CONFIG_SERIO
@@ -1198,10 +1198,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up)
        if (up->port.type == PORT_UNKNOWN)
                return -ENODEV;
 
-       printk("%s: %s port at %lx, irq %u\n",
+       printk("%s: %s port at %llx, irq %u\n",
               to_of_device(up->port.dev)->node->full_name,
               (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse",
-              up->port.mapbase, up->port.irq);
+              (unsigned long long) up->port.mapbase,
+              up->port.irq);
 
 #ifdef CONFIG_SERIO
        serio = &up->serio;
@@ -1328,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s,
  */
 static int __init sunsu_console_setup(struct console *co, char *options)
 {
+       static struct ktermios dummy;
+       struct ktermios termios;
        struct uart_port *port;
-       int baud = 9600;
-       int bits = 8;
-       int parity = 'n';
-       int flow = 'n';
 
        printk("Console: ttyS%d (SU)\n",
               (sunsu_reg.minor - 64) + co->index);
@@ -1351,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options)
         */
        spin_lock_init(&port->lock);
 
-       if (options)
-               uart_parse_options(options, &baud, &parity, &bits, &flow);
+       /* Get firmware console settings.  */
+       sunserial_console_termios(co, to_of_device(port->dev)->node);
+
+       memset(&termios, 0, sizeof(struct ktermios));
+       termios.c_cflag = co->cflag;
+       port->mctrl |= TIOCM_DTR;
+       port->ops->set_termios(port, &termios, &dummy);
 
-       return uart_set_options(port, co, baud, parity, bits, flow);
+       return 0;
 }
 
 static struct console sunsu_console = {
@@ -1408,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
        struct uart_sunsu_port *up;
        struct resource *rp;
        enum su_type type;
+       bool ignore_line;
        int err;
 
        type = su_get_type(dp);
@@ -1466,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
 
        up->port.ops = &sunsu_pops;
 
+       ignore_line = false;
+       if (!strcmp(dp->name, "rsc-console") ||
+           !strcmp(dp->name, "lom-console"))
+               ignore_line = true;
+
        sunserial_console_match(SUNSU_CONSOLE(), dp,
-                               &sunsu_reg, up->port.line);
+                               &sunsu_reg, up->port.line,
+                               ignore_line);
        err = uart_add_one_port(&sunsu_reg, &up->port);
        if (err)
                goto out_unmap;
@@ -1505,7 +1516,7 @@ static int __devexit su_remove(struct of_device *op)
        return 0;
 }
 
-static struct of_device_id su_match[] = {
+static const struct of_device_id su_match[] = {
        {
                .name = "su",
        },
@@ -1516,6 +1527,10 @@ static struct of_device_id su_match[] = {
                .name = "serial",
                .compatible = "su",
        },
+       {
+               .type = "serial",
+               .compatible = "su",
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, su_match);
@@ -1527,14 +1542,12 @@ static struct of_platform_driver su_driver = {
        .remove         = __devexit_p(su_remove),
 };
 
-static int num_uart;
-
 static int __init sunsu_init(void)
 {
        struct device_node *dp;
        int err;
+       int num_uart = 0;
 
-       num_uart = 0;
        for_each_node_by_name(dp, "su") {
                if (su_get_type(dp) == SU_PORT_PORT)
                        num_uart++;
@@ -1549,28 +1562,30 @@ static int __init sunsu_init(void)
                                num_uart++;
                }
        }
+       for_each_node_by_type(dp, "serial") {
+               if (of_device_is_compatible(dp, "su")) {
+                       if (su_get_type(dp) == SU_PORT_PORT)
+                               num_uart++;
+               }
+       }
 
        if (num_uart) {
-               sunsu_reg.minor = sunserial_current_minor;
-               sunsu_reg.nr = num_uart;
-               err = uart_register_driver(&sunsu_reg);
+               err = sunserial_register_minors(&sunsu_reg, num_uart);
                if (err)
                        return err;
-               sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
-               sunserial_current_minor += num_uart;
        }
 
        err = of_register_driver(&su_driver, &of_bus_type);
        if (err && num_uart)
-               uart_unregister_driver(&sunsu_reg);
+               sunserial_unregister_minors(&sunsu_reg, num_uart);
 
        return err;
 }
 
 static void __exit sunsu_exit(void)
 {
-       if (num_uart)
-               uart_unregister_driver(&sunsu_reg);
+       if (sunsu_reg.nr)
+               sunserial_unregister_minors(&sunsu_reg, sunsu_reg.nr);
 }
 
 module_init(sunsu_init);