Merge master.kernel.org:/home/rmk/linux-2.6-serial
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 23 Mar 2006 01:33:12 +0000 (17:33 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 23 Mar 2006 01:33:12 +0000 (17:33 -0800)
* master.kernel.org:/home/rmk/linux-2.6-serial:
  [SERIAL] Merge avlab serial board entries in parport_serial
  [SERIAL] kernel console should send CRLF not LFCR

1  2 
drivers/serial/s3c2410.c
drivers/serial/serial_txx9.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/serial/vr41xx_siu.c
include/linux/serial_core.h

diff --combined drivers/serial/s3c2410.c
index 00d7c0ad8cbfee7057dd2fed82ac91db5c9c81da,e4d701239702f6438ee6beab438c9d247aa76877..f5aac92fb7981b673250f8099c2b1dc7f0616ebe
@@@ -1066,8 -1066,6 +1066,8 @@@ static int s3c24xx_serial_init_port(str
        port->mapbase   = res->start;
        port->membase   = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
        port->irq       = platform_get_irq(platdev, 0);
 +      if (port->irq < 0)
 +              port->irq = 0;
  
        ourport->clk    = clk_get(&platdev->dev, "uart");
  
@@@ -1586,25 -1584,19 +1586,19 @@@ s3c24xx_serial_console_txrdy(struct uar
  }
  
  static void
- s3c24xx_serial_console_write(struct console *co, const char *s,
-                            unsigned int count)
+ s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
  {
-       int i;
        unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
+       while (!s3c24xx_serial_console_txrdy(port, ufcon))
+               barrier();
+       wr_regb(cons_uart, S3C2410_UTXH, ch);
+ }
  
-       for (i = 0; i < count; i++) {
-               while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon))
-                       barrier();
-               wr_regb(cons_uart, S3C2410_UTXH, s[i]);
-               if (s[i] == '\n') {
-                       while (!s3c24xx_serial_console_txrdy(cons_uart, ufcon))
-                               barrier();
-                       wr_regb(cons_uart, S3C2410_UTXH, '\r');
-               }
-       }
+ static void
+ s3c24xx_serial_console_write(struct console *co, const char *s,
+                            unsigned int count)
+ {
+       uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
  }
  
  static void __init
index 141173efd463435867cf2d4d97f644c4e93f458a,1a259cee1a986854da0aa4de1563829261a41022..b848b7d944129b17448fcc4873a428e56a619ee1
   *    1.02    Cleanup. (import 8250.c changes)
   *    1.03    Fix low-latency mode. (import 8250.c changes)
   *    1.04    Remove usage of deprecated functions, cleanup.
 + *    1.05    More strict check in verify_port.  Cleanup.
 + *    1.06    Do not insert a char caused previous overrun.
 + *            Fix some spin_locks.
 + *            Do not call uart_add_one_port for absent ports.
   */
  #include <linux/config.h>
  
@@@ -61,7 -57,7 +61,7 @@@
  #include <asm/io.h>
  #include <asm/irq.h>
  
 -static char *serial_version = "1.04";
 +static char *serial_version = "1.06";
  static char *serial_name = "TX39/49 Serial driver";
  
  #define PASS_LIMIT    256
@@@ -98,8 -94,6 +98,8 @@@
  #define UART_NR  4
  #endif
  
 +#define HIGH_BITS_OFFSET      ((sizeof(long)-sizeof(int))*8)
 +
  struct uart_txx9_port {
        struct uart_port        port;
  
@@@ -216,7 -210,7 +216,7 @@@ static inline unsigned int sio_in(struc
  {
        switch (up->port.iotype) {
        default:
 -              return *(volatile u32 *)(up->port.membase + offset);
 +              return __raw_readl(up->port.membase + offset);
        case UPIO_PORT:
                return inl(up->port.iobase + offset);
        }
@@@ -227,7 -221,7 +227,7 @@@ sio_out(struct uart_txx9_port *up, int 
  {
        switch (up->port.iotype) {
        default:
 -              *(volatile u32 *)(up->port.membase + offset) = value;
 +              __raw_writel(value, up->port.membase + offset);
                break;
        case UPIO_PORT:
                outl(value, up->port.iobase + offset);
@@@ -265,19 -259,34 +265,19 @@@ sio_quot_set(struct uart_txx9_port *up
  static void serial_txx9_stop_tx(struct uart_port *port)
  {
        struct uart_txx9_port *up = (struct uart_txx9_port *)port;
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&up->port.lock, flags);
        sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
 -      spin_unlock_irqrestore(&up->port.lock, flags);
  }
  
  static void serial_txx9_start_tx(struct uart_port *port)
  {
        struct uart_txx9_port *up = (struct uart_txx9_port *)port;
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&up->port.lock, flags);
        sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
 -      spin_unlock_irqrestore(&up->port.lock, flags);
  }
  
  static void serial_txx9_stop_rx(struct uart_port *port)
  {
        struct uart_txx9_port *up = (struct uart_txx9_port *)port;
 -      unsigned long flags;
 -
 -      spin_lock_irqsave(&up->port.lock, flags);
        up->port.read_status_mask &= ~TXX9_SIDISR_RDIS;
 -#if 0
 -      sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_RIE);
 -#endif
 -      spin_unlock_irqrestore(&up->port.lock, flags);
  }
  
  static void serial_txx9_enable_ms(struct uart_port *port)
@@@ -293,16 -302,12 +293,16 @@@ receive_chars(struct uart_txx9_port *up
        unsigned int disr = *status;
        int max_count = 256;
        char flag;
 +      unsigned int next_ignore_status_mask;
  
        do {
                ch = sio_in(up, TXX9_SIRFIFO);
                flag = TTY_NORMAL;
                up->port.icount.rx++;
  
 +              /* mask out RFDN_MASK bit added by previous overrun */
 +              next_ignore_status_mask =
 +                      up->port.ignore_status_mask & ~TXX9_SIDISR_RFDN_MASK;
                if (unlikely(disr & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER |
                                     TXX9_SIDISR_UFER | TXX9_SIDISR_UOER))) {
                        /*
                                up->port.icount.parity++;
                        else if (disr & TXX9_SIDISR_UFER)
                                up->port.icount.frame++;
 -                      if (disr & TXX9_SIDISR_UOER)
 +                      if (disr & TXX9_SIDISR_UOER) {
                                up->port.icount.overrun++;
 +                              /*
 +                               * The receiver read buffer still hold
 +                               * a char which caused overrun.
 +                               * Ignore next char by adding RFDN_MASK
 +                               * to ignore_status_mask temporarily.
 +                               */
 +                              next_ignore_status_mask |=
 +                                      TXX9_SIDISR_RFDN_MASK;
 +                      }
  
                        /*
                         * Mask off conditions which should be ingored.
                uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag);
  
        ignore_char:
 +              up->port.ignore_status_mask = next_ignore_status_mask;
                disr = sio_in(up, TXX9_SIDISR);
        } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
        spin_unlock(&up->port.lock);
@@@ -455,11 -450,14 +455,11 @@@ static unsigned int serial_txx9_get_mct
  static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
  {
        struct uart_txx9_port *up = (struct uart_txx9_port *)port;
 -      unsigned long flags;
  
 -      spin_lock_irqsave(&up->port.lock, flags);
        if (mctrl & TIOCM_RTS)
                sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
        else
                sio_set(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
 -      spin_unlock_irqrestore(&up->port.lock, flags);
  }
  
  static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
@@@ -786,14 -784,8 +786,14 @@@ static void serial_txx9_config_port(str
  static int
  serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser)
  {
 -      if (ser->irq < 0 ||
 -          ser->baud_base < 9600 || ser->type != PORT_TXX9)
 +      unsigned long new_port = ser->port;
 +      if (HIGH_BITS_OFFSET)
 +              new_port += (unsigned long)ser->port_high << HIGH_BITS_OFFSET;
 +      if (ser->type != port->type ||
 +          ser->irq != port->irq ||
 +          ser->io_type != port->iotype ||
 +          new_port != port->iobase ||
 +          (unsigned long)ser->iomem_base != port->mapbase)
                return -EINVAL;
        return 0;
  }
@@@ -835,8 -827,7 +835,8 @@@ static void __init serial_txx9_register
  
                up->port.line = i;
                up->port.ops = &serial_txx9_pops;
 -              uart_add_one_port(drv, &up->port);
 +              if (up->port.iobase || up->port.mapbase)
 +                      uart_add_one_port(drv, &up->port);
        }
  }
  
@@@ -863,6 -854,14 +863,14 @@@ static inline void wait_for_xmitr(struc
        }
  }
  
+ static void serial_txx9_console_putchar(struct uart_port *port, int ch)
+ {
+       struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+       wait_for_xmitr(up);
+       sio_out(up, TXX9_SITFIFO, ch);
+ }
  /*
   *    Print a string to the serial port trying not to disturb
   *    any possible real use of the port...
@@@ -874,7 -873,6 +882,6 @@@ serial_txx9_console_write(struct consol
  {
        struct uart_txx9_port *up = &serial_txx9_ports[co->index];
        unsigned int ier, flcr;
-       int i;
  
        /*
         *      First save the UER then disable the interrupts
        if (!(up->port.flags & UPF_CONS_FLOW) && (flcr & TXX9_SIFLCR_TES))
                sio_out(up, TXX9_SIFLCR, flcr & ~TXX9_SIFLCR_TES);
  
-       /*
-        *      Now, do each character
-        */
-       for (i = 0; i < count; i++, s++) {
-               wait_for_xmitr(up);
-               /*
-                *      Send the character out.
-                *      If a LF, also do CR...
-                */
-               sio_out(up, TXX9_SITFIFO, *s);
-               if (*s == 10) {
-                       wait_for_xmitr(up);
-                       sio_out(up, TXX9_SITFIFO, 13);
-               }
-       }
+       uart_console_write(&up->port, s, count, serial_txx9_console_putchar);
  
        /*
         *      Finally, wait for transmitter to become empty
@@@ -935,6 -918,11 +927,6 @@@ static int serial_txx9_console_setup(st
        if (!port->ops)
                return -ENODEV;
  
 -      /*
 -       * Temporary fix.
 -       */
 -      spin_lock_init(&port->lock);
 -
        /*
         *      Disable UART interrupts, set DTR and RTS high
         *      and set speed.
@@@ -1045,10 -1033,11 +1037,10 @@@ static int __devinit serial_txx9_regist
        mutex_lock(&serial_txx9_mutex);
        for (i = 0; i < UART_NR; i++) {
                uart = &serial_txx9_ports[i];
 -              if (uart->port.type == PORT_UNKNOWN)
 +              if (!(uart->port.iobase || uart->port.mapbase))
                        break;
        }
        if (i < UART_NR) {
 -              uart_remove_one_port(&serial_txx9_reg, &uart->port);
                uart->port.iobase = port->iobase;
                uart->port.membase = port->membase;
                uart->port.irq      = port->irq;
@@@ -1083,8 -1072,9 +1075,8 @@@ static void __devexit serial_txx9_unreg
        uart->port.type = PORT_UNKNOWN;
        uart->port.iobase = 0;
        uart->port.mapbase = 0;
 -      uart->port.membase = 0;
 +      uart->port.membase = NULL;
        uart->port.dev = NULL;
 -      uart_add_one_port(&serial_txx9_reg, &uart->port);
        mutex_unlock(&serial_txx9_mutex);
  }
  
@@@ -1200,11 -1190,8 +1192,11 @@@ static void __exit serial_txx9_exit(voi
  #ifdef ENABLE_SERIAL_TXX9_PCI
        pci_unregister_driver(&serial_txx9_pci_driver);
  #endif
 -      for (i = 0; i < UART_NR; i++)
 -              uart_remove_one_port(&serial_txx9_reg, &serial_txx9_ports[i].port);
 +      for (i = 0; i < UART_NR; i++) {
 +              struct uart_txx9_port *up = &serial_txx9_ports[i];
 +              if (up->port.iobase || up->port.mapbase)
 +                      uart_remove_one_port(&serial_txx9_reg, &up->port);
 +      }
  
        uart_unregister_driver(&serial_txx9_reg);
  }
diff --combined drivers/serial/sunsab.c
index a2fb0c2fb121ffde46db6b3c049f7147141303be,be95eabd0394069114c9c052c045275b0a82a3d5..bfbe9dc90ccaa4fbc2316c2ed1acb20fcf7e0aa2
@@@ -861,8 -861,9 +861,9 @@@ static int num_channels
  
  #ifdef CONFIG_SERIAL_SUNSAB_CONSOLE
  
- static __inline__ void sunsab_console_putchar(struct uart_sunsab_port *up, char c)
+ static void sunsab_console_putchar(struct uart_port *port, int c)
  {
+       struct uart_sunsab_port *up = (struct uart_sunsab_port *)port;
        unsigned long flags;
  
        spin_lock_irqsave(&up->port.lock, flags);
  static void sunsab_console_write(struct console *con, const char *s, unsigned n)
  {
        struct uart_sunsab_port *up = &sunsab_ports[con->index];
-       int i;
  
-       for (i = 0; i < n; i++) {
-               if (*s == '\n')
-                       sunsab_console_putchar(up, '\r');
-               sunsab_console_putchar(up, *s++);
-       }
+       uart_console_write(&up->port, s, n, sunsab_console_putchar);
        sunsab_tec_wait(up);
  }
  
@@@ -955,13 -951,14 +951,13 @@@ static struct console sunsab_console = 
        .index  =       -1,
        .data   =       &sunsab_reg,
  };
 -#define SUNSAB_CONSOLE        (&sunsab_console)
  
 -static void __init sunsab_console_init(void)
 +static inline struct console *SUNSAB_CONSOLE(void)
  {
        int i;
  
        if (con_is_present())
 -              return;
 +              return NULL;
  
        for (i = 0; i < num_channels; i++) {
                int this_minor = sunsab_reg.minor + i;
                        break;
        }
        if (i == num_channels)
 -              return;
 +              return NULL;
  
        sunsab_console.index = i;
 -      register_console(&sunsab_console);
 +
 +      return &sunsab_console;
  }
  #else
 -#define SUNSAB_CONSOLE                (NULL)
 +#define SUNSAB_CONSOLE()      (NULL)
  #define sunsab_console_init() do { } while (0)
  #endif
  
@@@ -1124,6 -1120,7 +1120,6 @@@ static int __init sunsab_init(void
  
        sunsab_reg.minor = sunserial_current_minor;
        sunsab_reg.nr = num_channels;
 -      sunsab_reg.cons = SUNSAB_CONSOLE;
  
        ret = uart_register_driver(&sunsab_reg);
        if (ret < 0) {
                return ret;
        }
  
 +      sunsab_reg.tty_driver->name_base = sunsab_reg.minor - 64;
 +
 +      sunsab_reg.cons = SUNSAB_CONSOLE();
 +
        sunserial_current_minor += num_channels;
        
 -      sunsab_console_init();
 -
        for (i = 0; i < num_channels; i++) {
                struct uart_sunsab_port *up = &sunsab_ports[i];
  
diff --combined drivers/serial/sunsu.c
index 46c44b83f57cbd883cc05070cb461a250962563a,9ca1d8b9364bc9ac865d193513eb65dde4dba4ec..7fc3d3b41d181d0752ee98d395b464ef6e645b28
@@@ -1280,7 -1280,6 +1280,7 @@@ static int __init sunsu_kbd_ms_init(str
        struct serio *serio;
  #endif
  
 +      spin_lock_init(&up->port.lock);
        up->port.line = channel;
        up->port.type = PORT_UNKNOWN;
        up->port.uartclk = (SU_BASE_BAUD * 16);
@@@ -1377,6 -1376,14 +1377,14 @@@ static __inline__ void wait_for_xmitr(s
        }
  }
  
+ static void sunsu_console_putchar(struct uart_port *port, int ch)
+ {
+       struct uart_sunsu_port *up = (struct uart_sunsu_port *)port;
+       wait_for_xmitr(up);
+       serial_out(up, UART_TX, ch);
+ }
  /*
   *    Print a string to the serial port trying not to disturb
   *    any possible real use of the port...
@@@ -1386,7 -1393,6 +1394,6 @@@ static void sunsu_console_write(struct 
  {
        struct uart_sunsu_port *up = &sunsu_ports[co->index];
        unsigned int ier;
-       int i;
  
        /*
         *      First save the UER then disable the interrupts
        ier = serial_in(up, UART_IER);
        serial_out(up, UART_IER, 0);
  
-       /*
-        *      Now, do each character
-        */
-       for (i = 0; i < count; i++, s++) {
-               wait_for_xmitr(up);
-               /*
-                *      Send the character out.
-                *      If a LF, also do CR...
-                */
-               serial_out(up, UART_TX, *s);
-               if (*s == 10) {
-                       wait_for_xmitr(up);
-                       serial_out(up, UART_TX, 13);
-               }
-       }
+       uart_console_write(&up->port, s, count, sunsu_console_putchar);
  
        /*
         *      Finally, wait for transmitter to become empty
@@@ -1465,17 -1456,18 +1457,17 @@@ static struct console sunsu_cons = 
        .index  =       -1,
        .data   =       &sunsu_reg,
  };
 -#define SUNSU_CONSOLE (&sunsu_cons)
  
  /*
   *    Register console.
   */
  
 -static int __init sunsu_serial_console_init(void)
 +static inline struct console *SUNSU_CONSOLE(void)
  {
        int i;
  
        if (con_is_present())
 -              return 0;
 +              return NULL;
  
        for (i = 0; i < UART_NR; i++) {
                int this_minor = sunsu_reg.minor + i;
                        break;
        }
        if (i == UART_NR)
 -              return 0;
 +              return NULL;
        if (sunsu_ports[i].port_node == 0)
 -              return 0;
 +              return NULL;
  
        sunsu_cons.index = i;
 -      register_console(&sunsu_cons);
 -      return 0;
 +
 +      return &sunsu_cons;
  }
  #else
 -#define SUNSU_CONSOLE                 (NULL)
 +#define SUNSU_CONSOLE()                       (NULL)
  #define sunsu_serial_console_init()   do { } while (0)
  #endif
  
@@@ -1510,7 -1502,6 +1502,7 @@@ static int __init sunsu_serial_init(voi
                    up->su_type == SU_PORT_KBD)
                        continue;
  
 +              spin_lock_init(&up->port.lock);
                up->port.flags |= UPF_BOOT_AUTOCONF;
                up->port.type = PORT_UNKNOWN;
                up->port.uartclk = (SU_BASE_BAUD * 16);
        }
  
        sunsu_reg.minor = sunserial_current_minor;
 -      sunserial_current_minor += instance;
  
        sunsu_reg.nr = instance;
 -      sunsu_reg.cons = SUNSU_CONSOLE;
  
        ret = uart_register_driver(&sunsu_reg);
        if (ret < 0)
                return ret;
  
 -      sunsu_serial_console_init();
 +      sunsu_reg.tty_driver->name_base = sunsu_reg.minor - 64;
 +
 +      sunserial_current_minor += instance;
 +
 +      sunsu_reg.cons = SUNSU_CONSOLE();
 +
        for (i = 0; i < UART_NR; i++) {
                struct uart_sunsu_port *up = &sunsu_ports[i];
  
index 10b35c6f287daacaf39c7514a436a547caf5dd12,b0c46b9a59304140204ae2050ead5e27d5929a2f..cd49ebbf4a45e46ad4cf91b945814985200d884e
@@@ -1252,8 -1252,9 +1252,9 @@@ static struct zilog_layout __iomem * __
  
  #define ZS_PUT_CHAR_MAX_DELAY 2000    /* 10 ms */
  
- static void sunzilog_put_char(struct zilog_channel __iomem *channel, unsigned char ch)
+ static void sunzilog_putchar(struct uart_port *port, int ch)
  {
+       struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
        int loops = ZS_PUT_CHAR_MAX_DELAY;
  
        /* This is a timed polling loop so do not switch the explicit
@@@ -1284,7 -1285,7 +1285,7 @@@ static int sunzilog_serio_write(struct 
  
        spin_lock_irqsave(&sunzilog_serio_lock, flags);
  
-       sunzilog_put_char(ZILOG_CHANNEL_FROM_PORT(&up->port), ch);
+       sunzilog_putchar(&up->port, ch);
  
        spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
  
@@@ -1325,16 -1326,10 +1326,10 @@@ static voi
  sunzilog_console_write(struct console *con, const char *s, unsigned int count)
  {
        struct uart_sunzilog_port *up = &sunzilog_port_table[con->index];
-       struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
        unsigned long flags;
-       int i;
  
        spin_lock_irqsave(&up->port.lock, flags);
-       for (i = 0; i < count; i++, s++) {
-               sunzilog_put_char(channel, *s);
-               if (*s == 10)
-                       sunzilog_put_char(channel, 13);
-       }
+       uart_console_write(&up->port, s, count, sunzilog_putchar);
        udelay(2);
        spin_unlock_irqrestore(&up->port.lock, flags);
  }
@@@ -1390,6 -1385,7 +1385,6 @@@ static struct console sunzilog_console 
        .index  =       -1,
        .data   =       &sunzilog_reg,
  };
 -#define SUNZILOG_CONSOLE      (&sunzilog_console)
  
  static int __init sunzilog_console_init(void)
  {
        register_console(&sunzilog_console);
        return 0;
  }
 +
 +static inline struct console *SUNZILOG_CONSOLE(void)
 +{
 +      int i;
 +
 +      if (con_is_present())
 +              return NULL;
 +
 +      for (i = 0; i < NUM_CHANNELS; i++) {
 +              int this_minor = sunzilog_reg.minor + i;
 +
 +              if ((this_minor - 64) == (serial_console - 1))
 +                      break;
 +      }
 +      if (i == NUM_CHANNELS)
 +              return NULL;
 +
 +      sunzilog_console.index = i;
 +      sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS;
 +
 +      return &sunzilog_console;
 +}
 +
  #else
 -#define SUNZILOG_CONSOLE      (NULL)
 +#define SUNZILOG_CONSOLE()    (NULL)
  #define sunzilog_console_init() do { } while (0)
  #endif
  
@@@ -1688,15 -1661,14 +1683,15 @@@ static int __init sunzilog_ports_init(v
        }
                
        sunzilog_reg.nr = uart_count;
 -      sunzilog_reg.cons = SUNZILOG_CONSOLE;
 -
        sunzilog_reg.minor = sunserial_current_minor;
 -      sunserial_current_minor += uart_count;
  
        ret = uart_register_driver(&sunzilog_reg);
        if (ret == 0) {
 -              sunzilog_console_init();
 +              sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
 +              sunzilog_reg.cons = SUNZILOG_CONSOLE();
 +
 +              sunserial_current_minor += uart_count;
 +
                for (i = 0; i < NUM_CHANNELS; i++) {
                        struct uart_sunzilog_port *up = &sunzilog_port_table[i];
  
index bd6294132c18ff81f29d09bdaf48f86a6b14ecb1,3f88b8e819376ed2001e96bbbbde289aa9845294..df5e8713fa312290efab20f4794d00d1391b258a
@@@ -821,25 -821,23 +821,23 @@@ static void wait_for_xmitr(struct uart_
        }
  }
  
+ static void siu_console_putchar(struct uart_port *port, int ch)
+ {
+       wait_for_xmitr(port);
+       siu_write(port, UART_TX, ch);
+ }
  static void siu_console_write(struct console *con, const char *s, unsigned count)
  {
        struct uart_port *port;
        uint8_t ier;
-       unsigned i;
  
        port = &siu_uart_ports[con->index];
  
        ier = siu_read(port, UART_IER);
        siu_write(port, UART_IER, 0);
  
-       for (i = 0; i < count && *s != '\0'; i++, s++) {
-               wait_for_xmitr(port);
-               siu_write(port, UART_TX, *s);
-               if (*s == '\n') {
-                       wait_for_xmitr(port);
-                       siu_write(port, UART_TX, '\r');
-               }
-       }
+       uart_console_write(port, s, count, siu_console_putchar);
  
        wait_for_xmitr(port);
        siu_write(port, UART_IER, ier);
@@@ -919,7 -917,7 +917,7 @@@ static struct uart_driver siu_uart_driv
        .cons           = SERIAL_VR41XX_CONSOLE,
  };
  
 -static int siu_probe(struct platform_device *dev)
 +static int __devinit siu_probe(struct platform_device *dev)
  {
        struct uart_port *port;
        int num, i, retval;
        return 0;
  }
  
 -static int siu_remove(struct platform_device *dev)
 +static int __devexit siu_remove(struct platform_device *dev)
  {
        struct uart_port *port;
        int i;
@@@ -1006,28 -1004,21 +1004,28 @@@ static struct platform_device *siu_plat
  
  static struct platform_driver siu_device_driver = {
        .probe          = siu_probe,
 -      .remove         = siu_remove,
 +      .remove         = __devexit_p(siu_remove),
        .suspend        = siu_suspend,
        .resume         = siu_resume,
        .driver         = {
                .name   = "SIU",
 +              .owner  = THIS_MODULE,
        },
  };
  
 -static int __devinit vr41xx_siu_init(void)
 +static int __init vr41xx_siu_init(void)
  {
        int retval;
  
 -      siu_platform_device = platform_device_register_simple("SIU", -1, NULL, 0);
 -      if (IS_ERR(siu_platform_device))
 -              return PTR_ERR(siu_platform_device);
 +      siu_platform_device = platform_device_alloc("SIU", -1);
 +      if (!siu_platform_device)
 +              return -ENOMEM;
 +
 +      retval = platform_device_add(siu_platform_device);
 +      if (retval < 0) {
 +              platform_device_put(siu_platform_device);
 +              return retval;
 +      }
  
        retval = platform_driver_register(&siu_device_driver);
        if (retval < 0)
        return retval;
  }
  
 -static void __devexit vr41xx_siu_exit(void)
 +static void __exit vr41xx_siu_exit(void)
  {
        platform_driver_unregister(&siu_device_driver);
 -
        platform_device_unregister(siu_platform_device);
  }
  
index 57abcea1cb5df956ee6b3b6adb662a8c99f366c1,f7434e5086f5c4c0d0fa2def26b8e8ff24e751ff..c32e60e79dea43b51b317b6d34e1d027165e6f93
  /* Hilscher netx */
  #define PORT_NETX     71
  
 +/* SUN4V Hypervisor Console */
 +#define PORT_SUNHV    72
 +
  #ifdef __KERNEL__
  
  #include <linux/config.h>
@@@ -369,6 -366,9 +369,9 @@@ void uart_parse_options(char *options, 
  int uart_set_options(struct uart_port *port, struct console *co, int baud,
                     int parity, int bits, int flow);
  struct tty_driver *uart_console_device(struct console *co, int *index);
+ void uart_console_write(struct uart_port *port, const char *s,
+                       unsigned int count,
+                       void (*putchar)(struct uart_port *, int));
  
  /*
   * Port/driver registration/removal