now that the gemini target is working, get rid of the obsolete and buggy storm target
[openwrt/svn-archive/archive.git] / target / linux / storm / patches / 008-serial.patch
diff --git a/target/linux/storm/patches/008-serial.patch b/target/linux/storm/patches/008-serial.patch
deleted file mode 100644 (file)
index a5c5e8d..0000000
+++ /dev/null
@@ -1,2809 +0,0 @@
---- /dev/null
-+++ b/drivers/serial/it8712.c
-@@ -0,0 +1,858 @@
-+/*
-+ *  linux/drivers/char/serial_uart00.c
-+ *
-+ *  Driver for UART00 serial ports
-+ *
-+ *  Based on drivers/char/serial_amba.c, by ARM Limited &
-+ *                                          Deep Blue Solutions Ltd.
-+ *  Copyright 2001 Altera Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ *  $Id: it8712.c,v 1.2 2006/06/06 06:36:04 middle Exp $
-+ *
-+ */
-+#include <linux/module.h>
-+#include <linux/tty.h>
-+#include <linux/ioport.h>
-+#include <linux/init.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+#include <asm/hardware.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+#include <asm/sizes.h>
-+
-+#if defined(CONFIG_SERIAL_IT8712_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <linux/serial_core.h>
-+#include <asm/arch/sl2312.h>
-+#include <asm/arch/int_ctrl.h>
-+#include <asm/arch/it8712.h>
-+#include "it8712.h"
-+
-+//#define DEBUG           1
-+#define UART_NR               1
-+
-+#define SERIAL_IT8712_NAME    "ttySI"
-+#define SERIAL_IT8712_MAJOR   204
-+#define SERIAL_IT8712_MINOR   41      /* Temporary - will change in future */
-+#define SERIAL_IT8712_NR      UART_NR
-+#define UART_PORT_SIZE 0x50
-+#define LPC_HOST_CONTINUE_MODE        0x00000040
-+
-+#define IT8712_NO_PORTS         UART_NR
-+#define IT8712_ISR_PASS_LIMIT 256
-+
-+#define LPC_BUS_CTRL  *(unsigned int*)(IO_ADDRESS(SL2312_LPC_HOST_BASE + 4))
-+#define LPC_BUS_STATUS        *(unsigned int*)(IO_ADDRESS(SL2312_LPC_HOST_BASE + 4))
-+#define LPC_SERIAL_IRQ_CTRL   *(unsigned int*)(IO_ADDRESS(SL2312_LPC_HOST_BASE + 8))
-+#define LPC_SERIAL_IRQ_STATUS *(unsigned int*)(IO_ADDRESS(SL2312_LPC_HOST_BASE + 0x0c))
-+#define LPC_SERIAL_IRQ_TRITYPE *(unsigned int*)(IO_ADDRESS(SL2312_LPC_HOST_BASE + 0x10))
-+#define LPC_SERIAL_IRQ_POLARITY       *(unsigned int*)(IO_ADDRESS(SL2312_LPC_HOST_BASE + 0x14))
-+#define LPC_SERIAL_IRQ_ENABLE *(unsigned int*)(IO_ADDRESS(SL2312_LPC_HOST_BASE + 0x18))
-+
-+
-+
-+
-+/*
-+ * Access macros for the SL2312 UARTs
-+ */
-+#define UART_GET_INT_STATUS(p)        (inb(((p)->membase+UART_IIR)) & 0x0F)  // interrupt identification
-+#define UART_PUT_IER(p, c)      outb(c,((p)->membase+UART_IER))         // interrupt enable
-+#define UART_GET_IER(p)         inb(((p)->membase+UART_IER))
-+#define UART_PUT_CHAR(p, c)     outb(c,((p)->membase+UART_TX))         // transmitter holding
-+#define UART_GET_CHAR(p)        inb(((p)->membase+UART_RX))            // receive buffer
-+#define UART_GET_LSR(p)         inb(((p)->membase+UART_LSR))            // line status
-+#define UART_GET_MSR(p)         inb(((p)->membase+UART_MSR))            // modem status
-+#define UART_GET_MCR(p)         inb(((p)->membase+UART_MCR))            // modem control
-+#define UART_PUT_MCR(p, c)      outb(c,((p)->membase+UART_MCR))
-+#define UART_GET_LCR(p)         inb(((p)->membase+UART_LCR))       // mode control
-+#define UART_PUT_LCR(p, c)      outb(c,((p)->membase+UART_LCR))
-+#define UART_PUT_FCR(p, c)      outb(c,((p)->membase+UART_FCR))       // fifo control
-+#define UART_GET_DIV_HI(p)    inb(((p)->membase+UART_DLM))
-+#define UART_PUT_DIV_HI(p, c) outb(c,((p)->membase+UART_DLM))
-+#define UART_GET_DIV_LO(p)    inb(((p)->membase+UART_DLL))
-+#define UART_PUT_DIV_LO(p, c) outb(c,((p)->membase+UART_DLL))
-+#define UART_PUT_MDR(p, c)      outb(c,UART_MDR((p)->membase))
-+#define UART_RX_DATA(s)               ((s) & UART_LSR_DR)
-+#define UART_TX_READY(s)      ((s) & UART_LSR_THRE)
-+
-+static void it8712_stop_tx(struct uart_port *port, u_int from_tty)
-+{
-+        unsigned int reg;
-+
-+        //printk("it8712 stop tx : \n");
-+        reg = UART_GET_IER(port);
-+        reg &= ~(UART_IER_THRI);
-+      UART_PUT_IER(port, reg);
-+}
-+
-+static void it8712_stop_rx(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+        //printk("it8712 stop rx : \n");
-+        reg = UART_GET_IER(port);
-+        reg &= ~(UART_IER_RDI);
-+      UART_PUT_IER(port, reg);
-+
-+}
-+
-+static void it8712_enable_ms(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+        //printk("it8712 enable ms : \n");
-+
-+        reg = UART_GET_IER(port);
-+        reg |= (UART_IER_MSI);
-+      UART_PUT_IER(port, reg);
-+
-+}
-+
-+static void it8712_rx_chars(struct uart_port *port, struct pt_regs *regs)
-+{
-+      struct tty_struct *tty = port->info->tty;
-+      unsigned int status, mask, ch, flg, ignored = 0;
-+
-+ //       printk("it8712_rx_chars : \n");
-+      status = UART_GET_LSR(port);
-+      while (UART_RX_DATA(status)) {
-+
-+              /*
-+               * We need to read rds before reading the
-+               * character from the fifo
-+               */
-+              ch = UART_GET_CHAR(port);
-+              port->icount.rx++;
-+
-+              if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+                      goto ignore_char;
-+
-+              flg = TTY_NORMAL;
-+
-+              /*
-+               * Note that the error handling code is
-+               * out of the main execution path
-+               */
-+
-+              if (status & (UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI|UART_LSR_DE))
-+                      goto handle_error;
-+              if (uart_handle_sysrq_char(port, ch, regs))
-+                      goto ignore_char;
-+
-+      error_return:
-+              *tty->flip.flag_buf_ptr++ = flg;
-+              *tty->flip.char_buf_ptr++ = ch;
-+              tty->flip.count++;
-+      ignore_char:
-+              status = UART_GET_LSR(port);
-+      } // end of while
-+out:
-+      tty_flip_buffer_push(tty);
-+      return;
-+
-+handle_error:
-+      if (status & UART_LSR_BI) {
-+              status &= ~(UART_LSR_FE);
-+              port->icount.brk++;
-+
-+#ifdef SUPPORT_SYSRQ
-+              if (uart_handle_break(port))
-+                      goto ignore_char;
-+#endif
-+      } else if (status & UART_LSR_PE)
-+              port->icount.parity++;
-+      else if (status & UART_LSR_FE)
-+              port->icount.frame++;
-+
-+      if (status & UART_LSR_OE)
-+              port->icount.overrun++;
-+
-+      if (status & port->ignore_status_mask) {
-+              if (++ignored > 100)
-+                      goto out;
-+              goto ignore_char;
-+      }
-+
-+      mask = status & port->read_status_mask;
-+
-+      if (mask & UART_LSR_BI)
-+              flg = TTY_BREAK;
-+      else if (mask & UART_LSR_PE)
-+              flg = TTY_PARITY;
-+      else if (mask & UART_LSR_FE)
-+              flg = TTY_FRAME;
-+
-+      if (status & UART_LSR_OE) {
-+              /*
-+               * CHECK: does overrun affect the current character?
-+               * ASSUMPTION: it does not.
-+               */
-+              *tty->flip.flag_buf_ptr++ = flg;
-+              *tty->flip.char_buf_ptr++ = ch;
-+              tty->flip.count++;
-+              if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+                      goto ignore_char;
-+              ch = 0;
-+              flg = TTY_OVERRUN;
-+      }
-+#ifdef SUPPORT_SYSRQ
-+      port->sysrq = 0;
-+#endif
-+      goto error_return;
-+}
-+
-+static void it8712_tx_chars(struct uart_port *port)
-+{
-+        struct circ_buf *xmit = &port->info->xmit;
-+      int count;
-+
-+      if (port->x_char) {
-+              while(!(UART_GET_LSR(port)&UART_LSR_THRE));
-+              UART_PUT_CHAR(port, port->x_char);
-+              port->icount.tx++;
-+              port->x_char = 0;
-+
-+              return;
-+      }
-+      if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-+              it8712_stop_tx(port, 0);
-+              return;
-+      }
-+
-+      count = port->fifosize >> 1;
-+      do {
-+              while(!(UART_GET_LSR(port)&UART_LSR_THRE));
-+              UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
-+              xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+              port->icount.tx++;
-+              if (uart_circ_empty(xmit))
-+                      break;
-+      } while (--count > 0);
-+
-+      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+              uart_write_wakeup(port);
-+
-+      if (uart_circ_empty(xmit))
-+              it8712_stop_tx(port, 0);
-+}
-+
-+static void it8712_start_tx(struct uart_port *port, unsigned int tty_start)
-+{
-+        unsigned int reg;
-+
-+        //printk("it8712 start tx : \n");
-+        reg = UART_GET_IER(port);
-+        reg |= (UART_IER_THRI);
-+      UART_PUT_IER(port, reg);
-+      it8712_tx_chars(port);
-+}
-+
-+static void it8712_modem_status(struct uart_port *port)
-+{
-+      unsigned int status;
-+
-+//        printk("it8712 modem status : \n");
-+
-+      status = UART_GET_MSR(port);
-+
-+      if (!(status & (UART_MSR_DCTS | UART_MSR_DDSR |
-+                     UART_MSR_TERI | UART_MSR_DDCD)))
-+              return;
-+
-+        if (status & UART_MSR_DDCD)
-+                uart_handle_dcd_change(port, status & UART_MSR_DCD);
-+
-+        if (status & UART_MSR_DDSR)
-+                port->icount.dsr++;
-+
-+        if (status & UART_MSR_DCTS)
-+                uart_handle_cts_change(port, status & UART_MSR_CTS);
-+
-+      wake_up_interruptible(&port->info->delta_msr_wait);
-+
-+}
-+
-+static irqreturn_t  it8712_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct uart_port *port = dev_id;
-+      unsigned int status, pass_counter = 0, data;
-+
-+
-+              data = LPC_SERIAL_IRQ_STATUS;
-+      if((data&0x10)==0x10)
-+      {
-+              status = UART_GET_INT_STATUS(port);
-+              do {
-+//                         printk("it8712_int: status %x \n", status);
-+                      switch(status)
-+                      {
-+                         case UART_IIR_RDI:
-+                         case UART_IIR_RLSI:
-+                         case UART_IIR_RCTO:
-+                              it8712_rx_chars(port, regs);
-+                         break;
-+                         case UART_IIR_THRI:
-+                              it8712_tx_chars(port);
-+                         break;
-+                         case UART_IIR_MSI:
-+                              it8712_modem_status(port);
-+                         break;
-+                         default:
-+                         break;
-+                      }
-+                      if (pass_counter++ > IT8712_ISR_PASS_LIMIT)
-+                              break;
-+
-+                      status = UART_GET_INT_STATUS(port);
-+              } while (status);
-+      }
-+
-+              status = 0;
-+        status |= (IRQ_LPC_MASK);
-+        *((volatile unsigned int *)IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = status;
-+
-+      //cnt=0;
-+      //do{
-+      //      data = LPC_SERIAL_IRQ_STATUS;
-+              LPC_SERIAL_IRQ_STATUS = data;
-+      //      cnt++;
-+      //}while(data);
-+      //if(cnt>2)
-+      //      printf("it8712_uart_Isr clear LPC_SERIAL_IRQ_STATUS %x \n", cnt);
-+        return IRQ_HANDLED;
-+}
-+
-+static u_int it8712_tx_empty(struct uart_port *port)
-+{
-+//        printk("it8712 tx empty : \n");
-+
-+      return ((UART_GET_LSR(port) & UART_LSR_THRE)? TIOCSER_TEMT : 0);
-+}
-+
-+static u_int it8712_get_mctrl(struct uart_port *port)
-+{
-+      unsigned int result = 0;
-+      unsigned int status;
-+
-+//        printk("it8712 get mctrl : \n");
-+
-+      status = UART_GET_MSR(port);
-+      if (status & UART_MSR_DCD)
-+              result |= TIOCM_CAR;
-+      if (status & UART_MSR_DSR)
-+              result |= TIOCM_DSR;
-+      if (status & UART_MSR_CTS)
-+              result |= TIOCM_CTS;
-+      if (status & UART_MSR_RI)
-+              result |= TIOCM_RI;
-+
-+      return result;
-+}
-+
-+static void it8712_set_mctrl_null(struct uart_port *port, u_int mctrl)
-+{
-+}
-+
-+static void it8712_break_ctl(struct uart_port *port, int break_state)
-+{
-+      unsigned int lcr;
-+
-+//        printk("it8712 break ctl : \n");
-+
-+      lcr = UART_GET_LCR(port);
-+      if (break_state == -1)
-+              lcr |= UART_LCR_SBC;
-+      else
-+              lcr &= ~UART_LCR_SBC;
-+      UART_PUT_LCR(port, lcr);
-+}
-+
-+static inline u_int uart_calculate_quot(struct uart_port *port, u_int baud)
-+{
-+      u_int quot;
-+
-+      /* Special case: B0 rate */
-+      if (!baud)
-+              baud = 9600;
-+
-+      quot = (port->uartclk/(16 * baud)) ;
-+
-+      return quot;
-+}
-+static void it8712_set_termios(struct uart_port *port, struct termios *termios,
-+                               struct termios *old)
-+{
-+      unsigned int  uart_mc, old_ier, baud, quot;
-+      unsigned long flags;
-+
-+        termios->c_cflag |= CREAD;
-+        termios->c_cflag |= CLOCAL;
-+#ifdef DEBUG
-+      printk("it8712_set_cflag(0x%x) called\n", cflag);
-+#endif
-+        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
-+        quot = uart_get_divisor(port, baud);
-+
-+      /* byte size and parity */
-+      switch (termios->c_cflag & CSIZE) {
-+      case CS5:
-+              uart_mc = UART_LCR_WLEN5;
-+              break;
-+      case CS6:
-+              uart_mc = UART_LCR_WLEN6;
-+              break;
-+      case CS7:
-+              uart_mc = UART_LCR_WLEN7;
-+              break;
-+      default: // CS8
-+              uart_mc = UART_LCR_WLEN8;
-+              break;
-+      }
-+
-+      if (termios->c_cflag & CSTOPB)
-+              uart_mc|= UART_LCR_STOP;
-+      if (termios->c_cflag & PARENB) {
-+              uart_mc |= UART_LCR_EVEN;
-+              if (!(termios->c_cflag & PARODD))
-+                      uart_mc |= UART_LCR_ODD;
-+      }
-+
-+        spin_lock_irqsave(&port->lock, flags);
-+        /*
-+         * Update the per-port timeout
-+         */
-+        uart_update_timeout(port, termios->c_cflag, baud);
-+      port->read_status_mask = UART_LSR_OE;
-+      if (termios->c_iflag & INPCK)
-+              port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-+      if (termios->c_iflag & (BRKINT | PARMRK))
-+              port->read_status_mask |= UART_LSR_BI;
-+
-+      /*
-+       * Characters to ignore
-+       */
-+      port->ignore_status_mask = 0;
-+      if (termios->c_iflag & IGNPAR)
-+              port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
-+      if (termios->c_iflag & IGNBRK) {
-+              port->ignore_status_mask |= UART_LSR_BI;
-+              /*
-+               * If we're ignoring parity and break indicators,
-+               * ignore overruns to (for real raw support).
-+               */
-+              if (termios->c_iflag & IGNPAR)
-+                      port->ignore_status_mask |= UART_LSR_OE;
-+      }
-+
-+      old_ier = UART_GET_IER(port);
-+
-+        if(UART_ENABLE_MS(port, termios->c_cflag))
-+             old_ier |= UART_IER_MSI;
-+
-+      /* Set baud rate */
-+      quot = quot / 13;
-+      UART_PUT_LCR(port, UART_LCR_DLAB);
-+      UART_PUT_DIV_LO(port, (quot & 0xff));
-+      UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
-+
-+      UART_PUT_LCR(port, uart_mc);
-+//    UART_PUT_LCR(port, 0x07); // ???? it is wired
-+        UART_PUT_MCR(port, 0x08);
-+        UART_PUT_FCR(port, 0x01);
-+      UART_PUT_IER(port, 0x07);
-+
-+      spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static int it8712_startup(struct uart_port *port)
-+{
-+      int retval, i;
-+      unsigned int regs;
-+
-+        //printk("it8712 startup : \n");
-+
-+      /*
-+       * Use iobase to store a pointer to info. We need this to start a
-+       * transmission as the tranmittr interrupt is only generated on
-+       * the transition to the idle state
-+       */
-+
-+      //      regs = 0;
-+    //    regs |= (IRQ_LPC_MASK);
-+    //    *((volatile unsigned int *)IRQ_CLEAR(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = regs;
-+
-+      /*
-+       * Allocate the IRQ
-+       */
-+      retval = request_irq(port->irq, it8712_int, SA_INTERRUPT, "it8712", port);
-+      if (retval)
-+              return retval;
-+
-+      //printk("Init LPC int...........\n");
-+        /* setup interrupt controller  */
-+        regs = *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
-+        regs &= ~(IRQ_LPC_MASK);
-+        *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = regs;
-+        regs = *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
-+        regs &= ~(IRQ_LPC_MASK);
-+        *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = regs;
-+        *((volatile unsigned int *)IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_LPC_MASK);
-+
-+      LPC_SERIAL_IRQ_POLARITY = 0x10; //0x10; //0x02;
-+      LPC_SERIAL_IRQ_TRITYPE = 0x10; //0x10;//
-+      LPC_SERIAL_IRQ_ENABLE = 0x10;
-+
-+      LPC_BUS_CTRL = 0xc0;
-+      LPC_SERIAL_IRQ_CTRL = 0xc0;
-+      for(i=0;i<1000;i++) ;
-+      LPC_SERIAL_IRQ_CTRL = 0x80;
-+      /*
-+       * Finally, enable interrupts. Use the TII interrupt to minimise
-+       * the number of interrupts generated. If higher performance is
-+       * needed, consider using the TI interrupt with a suitable FIFO
-+       * threshold
-+       */
-+      //UART_PUT_IER(port, (UART_IER_RDI|UART_IER_THRI));
-+      UART_PUT_IER(port, (UART_IER_RDI|UART_IER_THRI|UART_IER_RLSI));//middle
-+
-+      return 0;
-+}
-+
-+static void it8712_shutdown(struct uart_port *port)
-+{
-+        //printk("it8712 shutdown : \n");
-+
-+      /*
-+       * disable all interrupts, disable the port
-+       */
-+      UART_PUT_IER(port, 0x0);
-+
-+      /* disable break condition and fifos */
-+//    UART_PUT_MCR(port, (UART_GET_MCR(port)&UART_MCR_MASK));
-+
-+      /*
-+       * Free the interrupt
-+       */
-+      free_irq(port->irq, port);
-+}
-+
-+static const char *it8712_type(struct uart_port *port)
-+{
-+      return port->type == PORT_IT8712 ? "IT8712" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'
-+ */
-+static void it8712_release_port(struct uart_port *port)
-+{
-+//        printk("it8712 release port : \n");
-+
-+      release_mem_region(port->mapbase, UART_PORT_SIZE);
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'
-+ */
-+static int it8712_request_port(struct uart_port *port)
-+{
-+      return request_mem_region(port->mapbase, UART_PORT_SIZE,
-+                                  "serial_it8712") != NULL ? 0 : -EBUSY;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void it8712_config_port(struct uart_port *port, int flags)
-+{
-+
-+      if (flags & UART_CONFIG_TYPE) {
-+              if (it8712_request_port(port) == 0)
-+                      port->type = PORT_IT8712;
-+      }
-+}
-+
-+/*
-+ * verify the new serial_struct (for TIOCSSERIAL).
-+ */
-+static int it8712_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+      int ret = 0;
-+
-+      if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
-+              ret = -EINVAL;
-+      if (ser->irq < 0 || ser->irq >= NR_IRQS)
-+              ret = -EINVAL;
-+      if (ser->baud_base < 9600)
-+              ret = -EINVAL;
-+      return ret;
-+}
-+
-+static struct uart_ops it8712_pops = {
-+      .tx_empty       = it8712_tx_empty,
-+      .set_mctrl      = it8712_set_mctrl_null,
-+      .get_mctrl      = it8712_get_mctrl,
-+      .stop_tx        = it8712_stop_tx,
-+      .start_tx       = it8712_start_tx,
-+      .stop_rx        = it8712_stop_rx,
-+      .enable_ms      = it8712_enable_ms,
-+      .break_ctl      = it8712_break_ctl,
-+      .startup        = it8712_startup,
-+      .shutdown       = it8712_shutdown,
-+      .set_termios    = it8712_set_termios,
-+      .type           = it8712_type,
-+      .release_port   = it8712_release_port,
-+      .request_port   = it8712_request_port,
-+      .config_port    = it8712_config_port,
-+      .verify_port    = it8712_verify_port,
-+};
-+
-+#ifdef CONFIG_ARCH_SL2312
-+
-+static struct uart_port it8712_ports[UART_NR] = {
-+      {
-+              membase:        (void *)0,
-+              mapbase:        0,
-+              iotype:         SERIAL_IO_MEM,
-+              irq:            0,
-+              uartclk:        UART_CLK/2,
-+              fifosize:       16,
-+              ops:            &it8712_pops,
-+              flags:          ASYNC_BOOT_AUTOCONF,
-+      }
-+};
-+
-+#endif
-+
-+#ifdef CONFIG_SERIAL_IT8712_CONSOLE
-+#ifdef used_and_not_const_char_pointer
-+static int it8712_console_read(struct uart_port *port, char *s, u_int count)
-+{
-+      unsigned int status;
-+      int c;
-+#ifdef DEBUG
-+      printk("it8712_console_read() called\n");
-+#endif
-+
-+      c = 0;
-+      while (c < count) {
-+              status = UART_GET_LSR(port);
-+              if (UART_RX_DATA(status)) {
-+                      *s++ = UART_GET_CHAR(port);
-+                      c++;
-+              } else {
-+                      // nothing more to get, return
-+                      return c;
-+              }
-+      }
-+      // return the count
-+      return c;
-+}
-+#endif
-+static void it8712_console_write(struct console *co, const char *s, unsigned count)
-+{
-+#ifdef CONFIG_ARCH_SL2312
-+      struct uart_port *port = it8712_ports + co->index;
-+      unsigned int status, old_ies;
-+      int i;
-+
-+      /*
-+       *      First save the CR then disable the interrupts
-+       */
-+      old_ies = UART_GET_IER(port);
-+      //if(old_ies!=7)
-+      //{
-+      //
-+      //      printk("old_ies = %x\n",old_ies);
-+      //      old_ies = 7;
-+      //}
-+      UART_PUT_IER(port,0x0);
-+
-+      /*
-+       *      Now, do each character
-+       */
-+      for (i = 0; i < count; i++) {
-+              do {
-+                      status = UART_GET_LSR(port);
-+              } while (!UART_TX_READY(status));
-+              UART_PUT_CHAR(port, s[i]);
-+              if (s[i] == '\n') {
-+                      do {
-+                              status = UART_GET_LSR(port);
-+                      } while (!UART_TX_READY(status));
-+                      UART_PUT_CHAR(port, '\r');
-+              }
-+      }
-+
-+      /*
-+       *      Finally, wait for transmitter to become empty
-+       *      and restore the IES
-+       */
-+      do {
-+              status = UART_GET_LSR(port);
-+      } while (!(status&UART_LSR_THRE));
-+      UART_PUT_IER(port, old_ies);
-+#endif
-+}
-+
-+static void /*__init*/ it8712_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+      //printk("it8712 console get options : \n");
-+
-+      u_int uart_mc, quot;
-+      uart_mc= UART_GET_MCR(port);
-+
-+      *parity = 'n';
-+      if (uart_mc & UART_LCR_PARITY) {
-+              if (uart_mc & UART_LCR_EVEN)
-+                      *parity = 'e';
-+              else
-+                      *parity = 'o';
-+      }
-+
-+      switch (uart_mc & UART_LCR_MSK){
-+
-+      case UART_LCR_WLEN5:
-+              *bits = 5;
-+              break;
-+      case UART_LCR_WLEN6:
-+              *bits = 6;
-+              break;
-+      case UART_LCR_WLEN7:
-+              *bits = 7;
-+              break;
-+      case UART_LCR_WLEN8:
-+              *bits = 8;
-+              break;
-+      }
-+      UART_PUT_MCR(port,UART_LCR_DLAB);
-+      quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
-+      UART_PUT_MCR(port,uart_mc);
-+      *baud = (port->uartclk / (16 *quot));
-+}
-+
-+static int __init it8712_console_setup(struct console *co, char *options)
-+{
-+      struct uart_port *port;
-+      int baud = 38400;
-+      int bits = 8;
-+      int parity = 'n';
-+      int flow= 'n';
-+      int base;//, irq;
-+      int i ;
-+
-+      printk("it8712 console setup : \n");
-+
-+      LPCSetConfig(0, 0x02, 0x01);
-+        LPCSetConfig(LDN_SERIAL1, 0x30, 0x1);
-+        LPCSetConfig(LDN_SERIAL1, 0x23, 0x0);
-+      base = IT8712_IO_BASE;
-+      base += ((LPCGetConfig(LDN_SERIAL1, 0x60) << 8) + LPCGetConfig(LDN_SERIAL1, 0x61));
-+      it8712_ports[0].mapbase = base;
-+      it8712_ports[0].membase = (void *)IO_ADDRESS(base);
-+      it8712_ports[0].irq = IRQ_LPC_OFFSET;
-+    //        irq = LPCGetConfig(LDN_SERIAL1, 0x70);
-+      //it8712_ports[0].irq += irq;
-+
-+      //printk("it8712 irq is %x \n", it8712_ports[0].irq);
-+
-+      // setup LPC Host 'quiet mode'
-+      //*((volatile unsigned int *)IO_ADDRESS((SL2312_LPC_HOST_BASE+0x04))) |= LPC_HOST_CONTINUE_MODE ;
-+      //for(i=0;i<1000;i++) ;                                         // delay
-+      //*((volatile unsigned int *)IO_ADDRESS((SL2312_LPC_HOST_BASE+0x04))) &= ~(LPC_HOST_CONTINUE_MODE) ;
-+      LPC_BUS_CTRL = 0xc0;
-+      LPC_SERIAL_IRQ_CTRL = 0xc0;
-+      for(i=0;i<1000;i++) ;
-+      LPC_SERIAL_IRQ_CTRL = 0x80;
-+
-+#ifdef CONFIG_ARCH_SL2312
-+      /*
-+       * Check whether an invalid uart number has been specified, and
-+       * if so, search for the first available port that does have
-+       * console support.
-+       */
-+      port = uart_get_console(it8712_ports,IT8712_NO_PORTS,co);
-+#else
-+      return -ENODEV;
-+#endif
-+
-+      if (options)
-+              uart_parse_options(options, &baud, &parity, &bits, &flow);
-+      else
-+              it8712_console_get_options(port, &baud, &parity, &bits);
-+
-+      return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+extern struct uart_driver it8712_reg;
-+static struct console it8712_console = {
-+      .name           = SERIAL_IT8712_NAME,
-+      .write          = it8712_console_write,
-+      .device         = uart_console_device,
-+        .setup          = it8712_console_setup,
-+      .flags          = CON_PRINTBUFFER,
-+      .index          = 0,
-+        .data           = &it8712_reg,
-+};
-+
-+static int __init it8712_console_init(void)
-+{
-+      register_console(&it8712_console);
-+        return 0;
-+}
-+
-+console_initcall(it8712_console_init);
-+
-+#define IT8712_CONSOLE        &it8712_console
-+#else
-+#define IT8712_CONSOLE        NULL
-+#endif
-+
-+static struct uart_driver it8712_reg = {
-+      .owner                  = NULL,
-+      .driver_name            = SERIAL_IT8712_NAME,
-+      .dev_name               = SERIAL_IT8712_NAME,
-+        .major                  = SERIAL_IT8712_MAJOR,
-+      .minor                  = SERIAL_IT8712_MINOR,
-+      .nr                     = UART_NR,
-+      .cons                   = IT8712_CONSOLE,
-+};
-+
-+static int __init it8712_init(void)
-+{
-+        int result;
-+      //printk("serial_it8712: it871212_init \n");
-+
-+
-+        result = uart_register_driver(&it8712_reg);
-+        if(result)
-+             return result;
-+      result = uart_add_one_port(&it8712_reg, &it8712_ports[0]);
-+
-+        return result;
-+
-+}
-+
-+
-+__initcall(it8712_init);
---- /dev/null
-+++ b/drivers/serial/it8712.h
-@@ -0,0 +1,135 @@
-+#define UART_RX               0       /* In:  Receive buffer (DLAB=0) */
-+#define UART_TX               0       /* Out: Transmit buffer (DLAB=0) */
-+#define UART_DLL      0       /* Out: Divisor Latch Low (DLAB=1) */
-+#define UART_TRG      0       /* (LCR=BF) FCTR bit 7 selects Rx or Tx
-+                               * In: Fifo count
-+                               * Out: Fifo custom trigger levels
-+                               * XR16C85x only */
-+
-+#define UART_DLM      1       /* Out: Divisor Latch High (DLAB=1) */
-+#define UART_IER      1       /* Out: Interrupt Enable Register */
-+#define UART_FCTR     1       /* (LCR=BF) Feature Control Register
-+                               * XR16C85x only */
-+
-+#define UART_IIR      2       /* In:  Interrupt ID Register */
-+#define UART_FCR      2       /* Out: FIFO Control Register */
-+#define UART_EFR      2       /* I/O: Extended Features Register */
-+                              /* (DLAB=1, 16C660 only) */
-+
-+#define UART_LCR      3       /* Out: Line Control Register */
-+#define UART_MCR      4       /* Out: Modem Control Register */
-+#define UART_LSR      5       /* In:  Line Status Register */
-+#define UART_MSR      6       /* In:  Modem Status Register */
-+#define UART_SCR      7       /* I/O: Scratch Register */
-+#define UART_EMSR     7       /* (LCR=BF) Extended Mode Select Register
-+                               * FCTR bit 6 selects SCR or EMSR
-+                               * XR16c85x only */
-+
-+/*
-+ * These are the definitions for the FIFO Control Register
-+ * (16650 only)
-+ */
-+#define UART_FCR_ENABLE_FIFO  0x01 /* Enable the FIFO */
-+#define UART_FCR_CLEAR_RCVR   0x02 /* Clear the RCVR FIFO */
-+#define UART_FCR_CLEAR_XMIT   0x04 /* Clear the XMIT FIFO */
-+#define UART_FCR_DMA_SELECT   0x08 /* For DMA applications */
-+#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */
-+#define UART_FCR_TRIGGER_1    0x00 /* Mask for trigger set at 1 */
-+#define UART_FCR_TRIGGER_4    0x40 /* Mask for trigger set at 4 */
-+#define UART_FCR_TRIGGER_8    0x80 /* Mask for trigger set at 8 */
-+#define UART_FCR_TRIGGER_14   0xC0 /* Mask for trigger set at 14 */
-+/* 16650 redefinitions */
-+#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */
-+#define UART_FCR6_R_TRIGGER_16        0x40 /* Mask for receive trigger set at 4 */
-+#define UART_FCR6_R_TRIGGER_24  0x80 /* Mask for receive trigger set at 8 */
-+#define UART_FCR6_R_TRIGGER_28        0xC0 /* Mask for receive trigger set at 14 */
-+#define UART_FCR6_T_TRIGGER_16        0x00 /* Mask for transmit trigger set at 16 */
-+#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */
-+#define UART_FCR6_T_TRIGGER_24  0x20 /* Mask for transmit trigger set at 24 */
-+#define UART_FCR6_T_TRIGGER_30        0x30 /* Mask for transmit trigger set at 30 */
-+/* TI 16750 definitions */
-+#define UART_FCR7_64BYTE      0x20 /* Go into 64 byte mode */
-+
-+/*
-+ * These are the definitions for the Line Control Register
-+ *
-+ * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
-+ * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
-+ */
-+#define UART_LCR_DLAB 0x80    /* Divisor latch access bit */
-+#define UART_LCR_SBC  0x40    /* Set break control */
-+#define UART_LCR_SPAR 0x20    /* Stick parity (?) */
-+#define UART_LCR_EPAR 0x10    /* Even parity select */
-+#define UART_LCR_PARITY       0x08    /* Parity Enable */
-+#define UART_LCR_STOP 0x04    /* Stop bits: 0=1 stop bit, 1= 2 stop bits */
-+#define UART_LCR_WLEN5  0x00  /* Wordlength: 5 bits */
-+#define UART_LCR_WLEN6  0x01  /* Wordlength: 6 bits */
-+#define UART_LCR_WLEN7  0x02  /* Wordlength: 7 bits */
-+#define UART_LCR_WLEN8  0x03  /* Wordlength: 8 bits */
-+#define UART_LCR_EVEN   0x18    /* Even parity */
-+#define UART_LCR_ODD    0x08    /* Odd parity */
-+#define UART_LCR_MSK    0x03
-+/*
-+ * These are the definitions for the Line Status Register
-+ */
-+#define UART_LSR_DE     0x80    /* FIFO Data Error */
-+#define UART_LSR_TEMT 0x40    /* Transmitter empty */
-+#define UART_LSR_THRE 0x20    /* Transmit-hold-register empty */
-+#define UART_LSR_BI   0x10    /* Break interrupt indicator */
-+#define UART_LSR_FE   0x08    /* Frame error indicator */
-+#define UART_LSR_PE   0x04    /* Parity error indicator */
-+#define UART_LSR_OE   0x02    /* Overrun error indicator */
-+#define UART_LSR_DR   0x01    /* Receiver data ready */
-+
-+/*
-+ * These are the definitions for the Interrupt Identification Register
-+ */
-+#define UART_IIR_NO_INT       0x01    /* No interrupts pending */
-+#define UART_IIR_ID   0x06    /* Mask for the interrupt ID */
-+
-+#define UART_IIR_MSI  0x00    /* Modem status interrupt */
-+#define UART_IIR_THRI 0x02    /* Transmitter holding register empty */
-+#define UART_IIR_RDI  0x04    /* Receiver data interrupt */
-+#define UART_IIR_RLSI 0x06    /* Receiver line status interrupt */
-+#define UART_IIR_RCTO 0x0c    /* Receiver character timeout interrupt */
-+/*
-+ * These are the definitions for the Interrupt Enable Register
-+ */
-+#define UART_IER_MSI  0x08    /* Enable Modem status interrupt */
-+#define UART_IER_RLSI 0x04    /* Enable receiver line status interrupt */
-+#define UART_IER_THRI 0x02    /* Enable Transmitter holding register int. */
-+#define UART_IER_RDI  0x01    /* Enable receiver data interrupt */
-+/*
-+ * Sleep mode for ST16650 and TI16750.
-+ * Note that for 16650, EFR-bit 4 must be selected as well.
-+ */
-+#define UART_IERX_SLEEP  0x10 /* Enable sleep mode */
-+
-+/*
-+ * These are the definitions for the Modem Control Register
-+ */
-+#define UART_MCR_LOOP 0x10    /* Enable loopback test mode */
-+#define UART_MCR_OUT2 0x08    /* Out2 complement */
-+#define UART_MCR_OUT1 0x04    /* Out1 complement */
-+#define UART_MCR_RTS  0x02    /* RTS complement */
-+#define UART_MCR_DTR  0x01    /* DTR complement */
-+
-+/*
-+ * These are the definitions for the Modem Status Register
-+ */
-+#define UART_MSR_DCD  0x80    /* Data Carrier Detect */
-+#define UART_MSR_RI   0x40    /* Ring Indicator */
-+#define UART_MSR_DSR  0x20    /* Data Set Ready */
-+#define UART_MSR_CTS  0x10    /* Clear to Send */
-+#define UART_MSR_DDCD 0x08    /* Delta DCD */
-+#define UART_MSR_TERI 0x04    /* Trailing edge ring indicator */
-+#define UART_MSR_DDSR 0x02    /* Delta DSR */
-+#define UART_MSR_DCTS 0x01    /* Delta CTS */
-+#define UART_MSR_ANY_DELTA 0x0F       /* Any of the delta bits! */
-+
-+#define UART_PARITY_NONE      0x00
-+#define UART_PARITY_ODD               0x01
-+#define UART_PARITY_EVEN      0x02
-+
-+
-+
---- /dev/null
-+++ b/drivers/serial/serial_it8712.c
-@@ -0,0 +1,876 @@
-+/*
-+ *  linux/drivers/char/serial_uart00.c
-+ *
-+ *  Driver for UART00 serial ports
-+ *
-+ *  Based on drivers/char/serial_amba.c, by ARM Limited &
-+ *                                          Deep Blue Solutions Ltd.
-+ *  Copyright 2001 Altera Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ *  $Id: serial_it8712.c,v 1.1.1.1 2006/04/03 08:41:00 amos_lee Exp $
-+ *
-+ */
-+#include <linux/module.h>
-+
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/circ_buf.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+#include <asm/sizes.h>
-+
-+#if defined(CONFIG_SERIAL_IT8712_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <linux/serial_core.h>
-+#include <asm/arch/sl2312.h>
-+#include <asm/arch/int_ctrl.h>
-+#include <asm/arch/it8712.h>
-+#include "serial_it8712.h"
-+
-+//#define DEBUG           1
-+#define UART_NR               1
-+
-+#define SERIAL_IT8712_NAME    "ttySI"
-+#define SERIAL_IT8712_MAJOR   204
-+#define SERIAL_IT8712_MINOR   41      /* Temporary - will change in future */
-+#define SERIAL_IT8712_NR      UART_NR
-+#define UART_PORT_SIZE 0x50
-+
-+#define CALLOUT_IT8712_NAME   "cuaslI"
-+#define CALLOUT_IT8712_MAJOR  205
-+#define CALLOUT_IT8712_MINOR  41      /* Temporary - will change in future */
-+#define CALLOUT_IT8712_NR     UART_NR
-+#define LPC_HOST_CONTINUE_MODE        0x00000040
-+
-+#define IT8712_NO_PORTS         UART_NR
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *it8712_table[UART_NR];
-+static struct termios *it8712_termios[UART_NR], *it8712_termios_locked[UART_NR];
-+static struct console it8712_console;
-+
-+#define IT8712_ISR_PASS_LIMIT 256
-+
-+/*
-+ * Access macros for the SL2312 UARTs
-+ */
-+#define UART_GET_INT_STATUS(p)        (inb(((p)->membase+UART_IIR)) & 0x0F)  // interrupt identification
-+#define UART_PUT_IER(p, c)      outb(c,((p)->membase+UART_IER))         // interrupt enable
-+#define UART_GET_IER(p)         inb(((p)->membase+UART_IER))
-+#define UART_PUT_CHAR(p, c)     outb(c,((p)->membase+UART_TX))         // transmitter holding
-+#define UART_GET_CHAR(p)        inb(((p)->membase+UART_RX))            // receive buffer
-+#define UART_GET_LSR(p)         inb(((p)->membase+UART_LSR))            // line status
-+#define UART_GET_MSR(p)         inb(((p)->membase+UART_MSR))            // modem status
-+#define UART_GET_MCR(p)         inb(((p)->membase+UART_MCR))            // modem control
-+#define UART_PUT_MCR(p, c)      outb(c,((p)->membase+UART_MCR))
-+#define UART_GET_LCR(p)         inb(((p)->membase+UART_LCR))       // mode control
-+#define UART_PUT_LCR(p, c)      outb(c,((p)->membase+UART_LCR))
-+#define UART_PUT_FCR(p, c)      outb(c,((p)->membase+UART_FCR))       // fifo control
-+#define UART_GET_DIV_HI(p)    inb(((p)->membase+UART_DLM))
-+#define UART_PUT_DIV_HI(p, c) outb(c,((p)->membase+UART_DLM))
-+#define UART_GET_DIV_LO(p)    inb(((p)->membase+UART_DLL))
-+#define UART_PUT_DIV_LO(p, c) outb(c,((p)->membase+UART_DLL))
-+#define UART_PUT_MDR(p, c)      outb(c,UART_MDR((p)->membase))
-+#define UART_RX_DATA(s)               ((s) & UART_LSR_DR)
-+#define UART_TX_READY(s)      ((s) & UART_LSR_THRE)
-+
-+static void it8712_stop_tx(struct uart_port *port, u_int from_tty)
-+{
-+        unsigned int reg;
-+
-+//        printk("it8712 stop tx : \n");
-+        reg = UART_GET_IER(port);
-+        reg &= ~(UART_IER_THRI);
-+      UART_PUT_IER(port, reg);
-+}
-+
-+static void it8712_stop_rx(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+//        printk("it8712 stop rx : \n");
-+        reg = UART_GET_IER(port);
-+        reg &= ~(UART_IER_RDI);
-+      UART_PUT_IER(port, reg);
-+
-+}
-+
-+static void it8712_enable_ms(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+//        printk("it8712 enable ms : \n");
-+
-+        reg = UART_GET_IER(port);
-+        reg |= (UART_IER_MSI);
-+      UART_PUT_IER(port, reg);
-+
-+}
-+
-+static void
-+it8712_rx_chars(struct uart_info *info, struct pt_regs *regs)
-+{
-+      struct tty_struct *tty = info->tty;
-+      unsigned int status, mask, ch, flg, ignored = 0;
-+      struct uart_port *port = info->port;
-+
-+ //       printk("it8712_rx_chars : \n");
-+      status = UART_GET_LSR(port);
-+      while (UART_RX_DATA(status)) {
-+
-+              /*
-+               * We need to read rds before reading the
-+               * character from the fifo
-+               */
-+              ch = UART_GET_CHAR(port);
-+              port->icount.rx++;
-+
-+              if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+                      goto ignore_char;
-+
-+              flg = TTY_NORMAL;
-+
-+              /*
-+               * Note that the error handling code is
-+               * out of the main execution path
-+               */
-+
-+              if (status & (UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI|UART_LSR_DE))
-+                      goto handle_error;
-+              if (uart_handle_sysrq_char(info, ch, regs))
-+                      goto ignore_char;
-+
-+      error_return:
-+              *tty->flip.flag_buf_ptr++ = flg;
-+              *tty->flip.char_buf_ptr++ = ch;
-+              tty->flip.count++;
-+      ignore_char:
-+              status = UART_GET_LSR(port);
-+      } // end of while
-+out:
-+      tty_flip_buffer_push(tty);
-+      return;
-+
-+handle_error:
-+      if (status & UART_LSR_BI) {
-+              status &= ~(UART_LSR_FE);
-+              port->icount.brk++;
-+
-+#ifdef SUPPORT_SYSRQ
-+              if (uart_handle_break(info, &it8712_console))
-+                      goto ignore_char;
-+#endif
-+      } else if (status & UART_LSR_PE)
-+              port->icount.parity++;
-+      else if (status & UART_LSR_FE)
-+              port->icount.frame++;
-+
-+      if (status & UART_LSR_OE)
-+              port->icount.overrun++;
-+
-+      if (status & port->ignore_status_mask) {
-+              if (++ignored > 100)
-+                      goto out;
-+              goto ignore_char;
-+      }
-+
-+      mask = status & port->read_status_mask;
-+
-+      if (mask & UART_LSR_BI)
-+              flg = TTY_BREAK;
-+      else if (mask & UART_LSR_PE)
-+              flg = TTY_PARITY;
-+      else if (mask & UART_LSR_FE)
-+              flg = TTY_FRAME;
-+
-+      if (status & UART_LSR_OE) {
-+              /*
-+               * CHECK: does overrun affect the current character?
-+               * ASSUMPTION: it does not.
-+               */
-+              *tty->flip.flag_buf_ptr++ = flg;
-+              *tty->flip.char_buf_ptr++ = ch;
-+              tty->flip.count++;
-+              if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+                      goto ignore_char;
-+              ch = 0;
-+              flg = TTY_OVERRUN;
-+      }
-+#ifdef SUPPORT_SYSRQ
-+      info->sysrq = 0;
-+#endif
-+      goto error_return;
-+}
-+
-+static void it8712_tx_chars(struct uart_info *info)
-+{
-+      int count;
-+      struct uart_port *port=info->port;
-+
-+      if (port->x_char) {
-+              while(!(UART_GET_LSR(port)&UART_LSR_THRE));
-+              UART_PUT_CHAR(port, port->x_char);
-+              port->icount.tx++;
-+              port->x_char = 0;
-+
-+              return;
-+      }
-+      if (info->xmit.head == info->xmit.tail
-+          || info->tty->stopped
-+          || info->tty->hw_stopped) {
-+              it8712_stop_tx(info->port, 0);
-+              return;
-+      }
-+
-+      count = port->fifosize >> 1;
-+      do {
-+              while(!(UART_GET_LSR(port)&UART_LSR_THRE));
-+              UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
-+              info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1);
-+              port->icount.tx++;
-+              if (info->xmit.head == info->xmit.tail)
-+                      break;
-+      } while (--count > 0);
-+
-+      if (CIRC_CNT(info->xmit.head,
-+                   info->xmit.tail,
-+                   UART_XMIT_SIZE) < WAKEUP_CHARS)
-+              uart_event(info, EVT_WRITE_WAKEUP);
-+
-+      if (info->xmit.head == info->xmit.tail)
-+              it8712_stop_tx(info->port, 0);
-+}
-+
-+static void it8712_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
-+{
-+        unsigned int reg;
-+      struct uart_info *info=(struct uart_info*)(port->iobase);
-+
-+//        printk("it8712 start tx : \n");
-+        reg = UART_GET_IER(port);
-+        reg |= (UART_IER_THRI);
-+      UART_PUT_IER(port, reg);
-+      it8712_tx_chars(info);
-+}
-+
-+static void it8712_modem_status(struct uart_info *info)
-+{
-+      unsigned int status;
-+      struct uart_icount *icount = &info->port->icount;
-+
-+//        printk("it8712 modem status : \n");
-+
-+      status = UART_GET_MSR(info->port);
-+
-+      if (!(status & (UART_MSR_DCTS | UART_MSR_DDSR |
-+                     UART_MSR_TERI | UART_MSR_DDCD)))
-+              return;
-+
-+      if (status & UART_MSR_DCD) {
-+              icount->dcd++;
-+#ifdef CONFIG_HARD_PPS
-+              if ((info->flags & ASYNC_HARDPPS_CD) &&
-+                  (status & UART_MSR_DCD_MSK))
-+                      hardpps();
-+#endif
-+              if (info->flags & ASYNC_CHECK_CD) {
-+                      if (status & UART_MSR_DCD)
-+                              wake_up_interruptible(&info->open_wait);
-+                      else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-+                                 (info->flags & ASYNC_CALLOUT_NOHUP))) {
-+                              if (info->tty)
-+                                      tty_hangup(info->tty);
-+                      }
-+              }
-+      }
-+
-+      if (status & UART_MSR_DDSR)
-+              icount->dsr++;
-+
-+      if (status & UART_MSR_DCTS) {
-+              icount->cts++;
-+
-+              if (info->flags & ASYNC_CTS_FLOW) {
-+                      status &= UART_MSR_CTS;
-+
-+                      if (info->tty->hw_stopped) {
-+                              if (status) {
-+                                      info->tty->hw_stopped = 0;
-+                                      info->ops->start_tx(info->port, 1, 0);
-+                                      uart_event(info, EVT_WRITE_WAKEUP);
-+                              }
-+                      } else {
-+                              if (!status) {
-+                                      info->tty->hw_stopped = 1;
-+                                      info->ops->stop_tx(info->port, 0);
-+                              }
-+                      }
-+              }
-+      }
-+      wake_up_interruptible(&info->delta_msr_wait);
-+
-+}
-+
-+static void it8712_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+      struct uart_info *info = dev_id;
-+      unsigned int status, pass_counter = 0;
-+
-+      status = UART_GET_INT_STATUS(info->port);
-+      do {
-+//                 printk("it8712_int: status %x \n", status);
-+              switch(status)
-+              {
-+                 case UART_IIR_RDI:
-+                 case UART_IIR_RLSI:
-+                 case UART_IIR_RCTO:
-+                      it8712_rx_chars(info, regs);
-+                 break;
-+                 case UART_IIR_THRI:
-+                      it8712_tx_chars(info);
-+                 break;
-+                 case UART_IIR_MSI:
-+                      it8712_modem_status(info);
-+                 break;
-+                 default:
-+                 break;
-+              }
-+              if (pass_counter++ > IT8712_ISR_PASS_LIMIT)
-+                      break;
-+
-+              status = UART_GET_INT_STATUS(info->port);
-+      } while (status);
-+}
-+
-+static u_int it8712_tx_empty(struct uart_port *port)
-+{
-+//        printk("it8712 tx empty : \n");
-+
-+      return ((UART_GET_LSR(port) & UART_LSR_THRE)? TIOCSER_TEMT : 0);
-+}
-+
-+static u_int it8712_get_mctrl(struct uart_port *port)
-+{
-+      unsigned int result = 0;
-+      unsigned int status;
-+
-+//        printk("it8712 get mctrl : \n");
-+
-+      status = UART_GET_MSR(port);
-+      if (status & UART_MSR_DCD)
-+              result |= TIOCM_CAR;
-+      if (status & UART_MSR_DSR)
-+              result |= TIOCM_DSR;
-+      if (status & UART_MSR_CTS)
-+              result |= TIOCM_CTS;
-+      if (status & UART_MSR_RI)
-+              result |= TIOCM_RI;
-+
-+      return result;
-+}
-+
-+static void it8712_set_mctrl_null(struct uart_port *port, u_int mctrl)
-+{
-+}
-+
-+static void it8712_break_ctl(struct uart_port *port, int break_state)
-+{
-+      unsigned int lcr;
-+
-+//        printk("it8712 break ctl : \n");
-+
-+      lcr = UART_GET_LCR(port);
-+      if (break_state == -1)
-+              lcr |= UART_LCR_SBC;
-+      else
-+              lcr &= ~UART_LCR_SBC;
-+      UART_PUT_LCR(port, lcr);
-+}
-+
-+static inline u_int uart_calculate_quot(struct uart_info *info, u_int baud)
-+{
-+      u_int quot;
-+
-+      /* Special case: B0 rate */
-+      if (!baud)
-+              baud = 9600;
-+
-+      quot = (info->port->uartclk/(16 * baud)) ;
-+
-+      return quot;
-+}
-+static void it8712_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
-+{
-+      u_int uart_mc=0, old_ier;
-+      unsigned long flags;
-+
-+#ifdef DEBUG
-+      printk("it8712_set_cflag(0x%x) called\n", cflag);
-+#endif
-+
-+
-+      /* byte size and parity */
-+      switch (cflag & CSIZE) {
-+      case CS5: uart_mc = UART_LCR_WLEN5; break;
-+      case CS6: uart_mc = UART_LCR_WLEN6; break;
-+      case CS7: uart_mc = UART_LCR_WLEN7; break;
-+      default:  uart_mc = UART_LCR_WLEN8; break; // CS8
-+      }
-+      if (cflag & CSTOPB)
-+              uart_mc|= UART_LCR_STOP;
-+      if (cflag & PARENB) {
-+              uart_mc |= UART_LCR_EVEN;
-+              if (!(cflag & PARODD))
-+                      uart_mc |= UART_LCR_ODD;
-+      }
-+
-+      port->read_status_mask = UART_LSR_OE;
-+      if (iflag & INPCK)
-+              port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-+      if (iflag & (BRKINT | PARMRK))
-+              port->read_status_mask |= UART_LSR_BI;
-+
-+      /*
-+       * Characters to ignore
-+       */
-+      port->ignore_status_mask = 0;
-+      if (iflag & IGNPAR)
-+              port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
-+      if (iflag & IGNBRK) {
-+              port->ignore_status_mask |= UART_LSR_BI;
-+              /*
-+               * If we're ignoring parity and break indicators,
-+               * ignore overruns to (for real raw support).
-+               */
-+              if (iflag & IGNPAR)
-+                      port->ignore_status_mask |= UART_LSR_OE;
-+      }
-+
-+      /* first, disable everything */
-+      save_flags(flags); cli();
-+      old_ier = UART_GET_IER(port);
-+
-+      if ((port->flags & ASYNC_HARDPPS_CD) ||
-+          (cflag & CRTSCTS) || !(cflag & CLOCAL))
-+              old_ier |= UART_IER_MSI;
-+
-+      /* Set baud rate */
-+      quot = quot / 13;
-+      UART_PUT_LCR(port, UART_LCR_DLAB);
-+      UART_PUT_DIV_LO(port, (quot & 0xff));
-+      UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
-+
-+      UART_PUT_LCR(port, uart_mc);
-+//    UART_PUT_LCR(port, 0x07); // ???? it is wired
-+        UART_PUT_MCR(port, 0x08);
-+        UART_PUT_FCR(port, 0x01);
-+      UART_PUT_IER(port, 0x05);
-+
-+      restore_flags(flags);
-+}
-+
-+static int it8712_startup(struct uart_port *port, struct uart_info *info)
-+{
-+      int retval;
-+      unsigned int regs;
-+
-+//        printk("it8712 startup : \n");
-+
-+      /*
-+       * Use iobase to store a pointer to info. We need this to start a
-+       * transmission as the tranmittr interrupt is only generated on
-+       * the transition to the idle state
-+       */
-+
-+      port->iobase=(u_int)info;
-+
-+      /*
-+       * Allocate the IRQ
-+       */
-+      retval = request_irq(port->irq, it8712_int, SA_INTERRUPT, "it8712", info);
-+      if (retval)
-+              return retval;
-+
-+        /* setup interrupt controller  */
-+        regs = *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
-+        regs |= (IRQ_SERIRQ0_MASK);
-+        *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = regs;
-+        regs = *((volatile unsigned int *)IRQ_LEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
-+        regs &= ~(IRQ_SERIRQ0_MASK);
-+        *((volatile unsigned int *)IRQ_LEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = regs;
-+        *((volatile unsigned int *)IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_SERIRQ0_MASK);
-+
-+      /*
-+       * Finally, enable interrupts. Use the TII interrupt to minimise
-+       * the number of interrupts generated. If higher performance is
-+       * needed, consider using the TI interrupt with a suitable FIFO
-+       * threshold
-+       */
-+      UART_PUT_IER(port, (UART_IER_RDI|UART_IER_THRI));
-+
-+      return 0;
-+}
-+
-+static void it8712_shutdown(struct uart_port *port, struct uart_info *info)
-+{
-+//        printk("it8712 shutdown : \n");
-+
-+      /*
-+       * disable all interrupts, disable the port
-+       */
-+      UART_PUT_IER(port, 0x0);
-+
-+      /* disable break condition and fifos */
-+//    UART_PUT_MCR(port, (UART_GET_MCR(port)&UART_MCR_MASK));
-+
-+      /*
-+       * Free the interrupt
-+       */
-+      free_irq(port->irq, info);
-+}
-+
-+static const char *it8712_type(struct uart_port *port)
-+{
-+      return port->type == PORT_IT8712 ? "IT8712" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'
-+ */
-+static void it8712_release_port(struct uart_port *port)
-+{
-+//        printk("it8712 release port : \n");
-+
-+      release_mem_region(port->mapbase, UART_PORT_SIZE);
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'
-+ */
-+static int it8712_request_port(struct uart_port *port)
-+{
-+      return request_mem_region(port->mapbase, UART_PORT_SIZE,
-+                                  "serial_it8712") != NULL ? 0 : -EBUSY;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void it8712_config_port(struct uart_port *port, int flags)
-+{
-+
-+      if (flags & UART_CONFIG_TYPE) {
-+              if (it8712_request_port(port) == 0)
-+                      port->type = PORT_IT8712;
-+      }
-+}
-+
-+/*
-+ * verify the new serial_struct (for TIOCSSERIAL).
-+ */
-+static int it8712_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+      int ret = 0;
-+
-+      if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
-+              ret = -EINVAL;
-+      if (ser->irq < 0 || ser->irq >= NR_IRQS)
-+              ret = -EINVAL;
-+      if (ser->baud_base < 9600)
-+              ret = -EINVAL;
-+      return ret;
-+}
-+
-+static struct uart_ops it8712_pops = {
-+      tx_empty:       it8712_tx_empty,
-+      set_mctrl:      it8712_set_mctrl_null,
-+      get_mctrl:      it8712_get_mctrl,
-+      stop_tx:        it8712_stop_tx,
-+      start_tx:       it8712_start_tx,
-+      stop_rx:        it8712_stop_rx,
-+      enable_ms:      it8712_enable_ms,
-+      break_ctl:      it8712_break_ctl,
-+      startup:        it8712_startup,
-+      shutdown:       it8712_shutdown,
-+      change_speed:   it8712_change_speed,
-+      type:           it8712_type,
-+      release_port:   it8712_release_port,
-+      request_port:   it8712_request_port,
-+      config_port:    it8712_config_port,
-+      verify_port:    it8712_verify_port,
-+};
-+
-+#ifdef CONFIG_ARCH_SL2312
-+
-+static struct uart_port it8712_ports[UART_NR] = {
-+      {
-+              membase:        (void *)0,
-+              mapbase:        0,
-+              iotype:         SERIAL_IO_MEM,
-+              irq:            0,
-+              uartclk:        UART_CLK/2,
-+              fifosize:       16,
-+              ops:            &it8712_pops,
-+              flags:          ASYNC_BOOT_AUTOCONF,
-+      }
-+};
-+
-+#endif
-+
-+#ifdef CONFIG_SERIAL_IT8712_CONSOLE
-+#ifdef used_and_not_const_char_pointer
-+static int it8712_console_read(struct uart_port *port, char *s, u_int count)
-+{
-+      unsigned int status;
-+      int c;
-+#ifdef DEBUG
-+      printk("it8712_console_read() called\n");
-+#endif
-+
-+      c = 0;
-+      while (c < count) {
-+              status = UART_GET_LSR(port);
-+              if (UART_RX_DATA(status)) {
-+                      *s++ = UART_GET_CHAR(port);
-+                      c++;
-+              } else {
-+                      // nothing more to get, return
-+                      return c;
-+              }
-+      }
-+      // return the count
-+      return c;
-+}
-+#endif
-+static void it8712_console_write(struct console *co, const char *s, unsigned count)
-+{
-+#ifdef CONFIG_ARCH_SL2312
-+      struct uart_port *port = it8712_ports + co->index;
-+      unsigned int status, old_ies;
-+      int i;
-+
-+      /*
-+       *      First save the CR then disable the interrupts
-+       */
-+      old_ies = UART_GET_IER(port);
-+      UART_PUT_IER(port,0x0);
-+
-+      /*
-+       *      Now, do each character
-+       */
-+      for (i = 0; i < count; i++) {
-+              do {
-+                      status = UART_GET_LSR(port);
-+              } while (!UART_TX_READY(status));
-+              UART_PUT_CHAR(port, s[i]);
-+              if (s[i] == '\n') {
-+                      do {
-+                              status = UART_GET_LSR(port);
-+                      } while (!UART_TX_READY(status));
-+                      UART_PUT_CHAR(port, '\r');
-+              }
-+      }
-+
-+      /*
-+       *      Finally, wait for transmitter to become empty
-+       *      and restore the IES
-+       */
-+      do {
-+              status = UART_GET_LSR(port);
-+      } while (!(status&UART_LSR_THRE));
-+      UART_PUT_IER(port, old_ies);
-+#endif
-+}
-+
-+static kdev_t it8712_console_device(struct console *co)
-+{
-+      return MKDEV(SERIAL_IT8712_MAJOR, SERIAL_IT8712_MINOR + co->index);
-+}
-+
-+static int it8712_console_wait_key(struct console *co)
-+{
-+#ifdef CONFIG_ARCH_SL2312
-+      struct uart_port *port = (it8712_ports + co->index);
-+      unsigned int status;
-+
-+      do {
-+              status = UART_GET_LSR(port);
-+      } while (!UART_RX_DATA(status));
-+      return UART_GET_CHAR(port);
-+#else
-+      return 0;
-+#endif
-+}
-+
-+static void /*__init*/ it8712_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+      printk("it8712 console get options : \n");
-+
-+      u_int uart_mc, quot;
-+      uart_mc= UART_GET_MCR(port);
-+
-+      *parity = 'n';
-+      if (uart_mc & UART_LCR_PARITY) {
-+              if (uart_mc & UART_LCR_EVEN)
-+                      *parity = 'e';
-+              else
-+                      *parity = 'o';
-+      }
-+
-+      switch (uart_mc & UART_LCR_MSK){
-+
-+      case UART_LCR_WLEN5:
-+              *bits = 5;
-+              break;
-+      case UART_LCR_WLEN6:
-+              *bits = 6;
-+              break;
-+      case UART_LCR_WLEN7:
-+              *bits = 7;
-+              break;
-+      case UART_LCR_WLEN8:
-+              *bits = 8;
-+              break;
-+      }
-+      UART_PUT_MCR(port,UART_LCR_DLAB);
-+      quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
-+      UART_PUT_MCR(port,uart_mc);
-+      *baud = (port->uartclk / (16 *quot));
-+}
-+
-+static int __init it8712_console_setup(struct console *co, char *options)
-+{
-+      struct uart_port *port;
-+      int baud = 38400;
-+      int bits = 8;
-+      int parity = 'n';
-+      int flow= 'n';
-+      int base, irq;
-+      int i ;
-+
-+//    printk("it8712 console setup : \n");
-+
-+      LPCSetConfig(0, 0x02, 0x01);
-+        LPCSetConfig(LDN_SERIAL1, 0x30, 0x1);
-+        LPCSetConfig(LDN_SERIAL1, 0x23, 0x0);
-+      base = IT8712_IO_BASE;
-+      base += ((LPCGetConfig(LDN_SERIAL1, 0x60) << 8) + LPCGetConfig(LDN_SERIAL1, 0x61));
-+      it8712_ports[0].mapbase = base;
-+      it8712_ports[0].membase = IO_ADDRESS(base);
-+      it8712_ports[0].irq = IRQ_SERIRQ0_OFFSET;
-+              irq = LPCGetConfig(LDN_SERIAL1, 0x70);
-+      it8712_ports[0].irq += irq;
-+
-+      printk("it8712 irq is %x %x \n", it8712_ports[0].irq, irq);
-+
-+      // setup LPC Host 'quiet mode'
-+      *((volatile unsigned int *)IO_ADDRESS((SL2312_LPC_HOST_BASE+0x04))) |= LPC_HOST_CONTINUE_MODE ;
-+      for(i=0;i<1000;i++) ;                                           // delay
-+      *((volatile unsigned int *)IO_ADDRESS((SL2312_LPC_HOST_BASE+0x04))) &= ~(LPC_HOST_CONTINUE_MODE) ;
-+
-+#ifdef CONFIG_ARCH_SL2312
-+      /*
-+       * Check whether an invalid uart number has been specified, and
-+       * if so, search for the first available port that does have
-+       * console support.
-+       */
-+      port = uart_get_console(it8712_ports,IT8712_NO_PORTS,co);
-+#else
-+      return -ENODEV;
-+#endif
-+
-+      if (options)
-+              uart_parse_options(options, &baud, &parity, &bits, &flow);
-+      else
-+              it8712_console_get_options(port, &baud, &parity, &bits);
-+
-+      return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console it8712_console = {
-+      name:           SERIAL_IT8712_NAME,
-+      write:          it8712_console_write,
-+#ifdef used_and_not_const_char_pointer
-+      read:           it8712_console_read,
-+#endif
-+      device:         it8712_console_device,
-+//    wait_key:       it8712_console_wait_key,
-+      setup:          it8712_console_setup,
-+      flags:          (CON_PRINTBUFFER|CON_ENABLED),
-+      index:          -1,
-+};
-+
-+void __init it8712_console_init(void)
-+{
-+      register_console(&it8712_console);
-+}
-+
-+#define IT8712_CONSOLE        &it8712_console
-+#else
-+#define IT8712_CONSOLE        NULL
-+#endif
-+
-+static struct uart_driver it8712_reg = {
-+      owner:                  NULL,
-+      normal_major:           SERIAL_IT8712_MAJOR,
-+      normal_name:            SERIAL_IT8712_NAME,
-+      normal_driver:          &normal,
-+      callout_major:          CALLOUT_IT8712_MAJOR,
-+      callout_name:           CALLOUT_IT8712_NAME,
-+      callout_driver:         &callout,
-+      table:                  it8712_table,
-+      termios:                it8712_termios,
-+      termios_locked:         it8712_termios_locked,
-+      minor:                  SERIAL_IT8712_MINOR,
-+      nr:                     UART_NR,
-+#ifdef CONFIG_ARCH_SL2312
-+      port:                   it8712_ports,
-+#endif
-+      state:                  NULL,
-+      cons:                   IT8712_CONSOLE,
-+};
-+
-+static int __init it8712_init(void)
-+{
-+//    printk("serial_it8712: it871212_init \n");
-+
-+      return uart_register_driver(&it8712_reg);
-+}
-+
-+
-+__initcall(it8712_init);
---- /dev/null
-+++ b/drivers/serial/serial_sl2312.c
-@@ -0,0 +1,827 @@
-+/*
-+ *  linux/drivers/char/serial_uart00.c
-+ *
-+ *  Driver for UART00 serial ports
-+ *
-+ *  Based on drivers/char/serial_amba.c, by ARM Limited &
-+ *                                          Deep Blue Solutions Ltd.
-+ *  Copyright 2001 Altera Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ *  $Id: serial_sl2312.c,v 1.1.1.1 2006/04/03 08:41:00 amos_lee Exp $
-+ *
-+ */
-+#include <linux/module.h>
-+
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/circ_buf.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+#include <linux/serial_core.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+#include <asm/sizes.h>
-+#include <linux/spinlock.h>
-+#include <linux/irq.h>
-+
-+
-+#if defined(CONFIG_SERIAL_SL2312_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <asm/arch/sl2312.h>
-+#define UART_TYPE (volatile unsigned int*)
-+#include <asm/arch/uart.h>
-+#include <asm/arch/int_ctrl.h>
-+
-+// #define DEBUG           1
-+#define UART_NR               1
-+
-+
-+#define SERIAL_SL2312_NAME    "ttyS"
-+#define SERIAL_SL2312_MAJOR   204
-+#define SERIAL_SL2312_MINOR   40      /* Temporary - will change in future */
-+#define SERIAL_SL2312_NR      UART_NR
-+#define UART_PORT_SIZE 0x50
-+
-+#define SL2312_NO_PORTS         UART_NR
-+#define SL2312_ISR_PASS_LIMIT 256
-+
-+/*
-+ * Access macros for the SL2312 UARTs
-+ */
-+#define UART_GET_INT_STATUS(p)        (inl(UART_IIR((p)->membase)) & 0x0F)      // interrupt identification
-+#define UART_PUT_IER(p, c)      outl(c,UART_IER((p)->membase))    // interrupt enable
-+#define UART_GET_IER(p)         inl(UART_IER((p)->membase))
-+#define UART_PUT_CHAR(p, c)     outl(c,UART_THR((p)->membase))    // transmitter holding
-+#define UART_GET_CHAR(p)        inl(UART_RBR((p)->membase))       // receive buffer
-+#define UART_GET_LSR(p)         inl(UART_LSR((p)->membase))       // line status
-+#define UART_GET_MSR(p)         inl(UART_MSR((p)->membase))       // modem status
-+#define UART_GET_MCR(p)         inl(UART_MCR((p)->membase))       // modem control
-+#define UART_PUT_MCR(p, c)      outl(c,UART_MCR((p)->membase))
-+#define UART_GET_LCR(p)         inl(UART_LCR((p)->membase))       // mode control
-+#define UART_PUT_LCR(p, c)      outl(c,UART_LCR((p)->membase))
-+#define UART_GET_DIV_HI(p)    inl(UART_DIV_HI((p)->membase))
-+#define UART_PUT_DIV_HI(p, c) outl(c,UART_DIV_HI((p)->membase))
-+#define UART_GET_DIV_LO(p)    inl(UART_DIV_LO((p)->membase))
-+#define UART_PUT_DIV_LO(p, c) outl(c,UART_DIV_LO((p)->membase))
-+#define UART_PUT_MDR(p, c)      outl(c,UART_MDR((p)->membase))
-+#define UART_RX_DATA(s)               ((s) & UART_LSR_DR)
-+#define UART_TX_READY(s)      ((s) & UART_LSR_THRE)
-+
-+
-+static void sl2312_stop_tx(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+//        printk("sl2312 stop tx : \n");
-+        reg = UART_GET_IER(port);
-+        reg &= ~(UART_IER_TE);
-+      UART_PUT_IER(port, reg);
-+}
-+
-+static void sl2312_stop_rx(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+//        printk("sl2312 stop rx : \n");
-+        reg = UART_GET_IER(port);
-+        reg &= ~(UART_IER_DR);
-+      UART_PUT_IER(port, reg);
-+
-+}
-+
-+static void sl2312_enable_ms(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+//        printk("sl2312 enable ms : \n");
-+
-+        reg = UART_GET_IER(port);
-+        reg |= (UART_IER_MS);
-+      UART_PUT_IER(port, reg);
-+
-+}
-+
-+static void
-+sl2312_rx_chars(struct uart_port *port)
-+{
-+      struct tty_struct *tty = port->info->tty;
-+      unsigned int status, mask, ch, flg, ignored = 0;
-+
-+
-+ //       printk("sl2312_rx_chars : \n");
-+      status = UART_GET_LSR(port);
-+      while (UART_RX_DATA(status)) {
-+
-+              /*
-+               * We need to read rds before reading the
-+               * character from the fifo
-+               */
-+              ch = UART_GET_CHAR(port);
-+              port->icount.rx++;
-+
-+              //if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+              if (tty && !tty_buffer_request_room(tty, 1))
-+                      goto ignore_char;
-+
-+              flg = TTY_NORMAL;
-+
-+              /*
-+               * Note that the error handling code is
-+               * out of the main execution path
-+               */
-+
-+              if (status & (UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI|UART_LSR_DE))
-+                      goto handle_error;
-+              if (uart_handle_sysrq_char(port, ch))
-+                      goto ignore_char;
-+
-+      error_return:
-+              //*tty->flip.flag_buf_ptr++ = flg;
-+              //*tty->flip.char_buf_ptr++ = ch;
-+              //tty->flip.count++;
-+              tty_insert_flip_char(tty, ch, flg);
-+      ignore_char:
-+              status = UART_GET_LSR(port);
-+      } // end of while
-+out:
-+      tty_flip_buffer_push(tty);
-+      return;
-+
-+handle_error:
-+      if (status & UART_LSR_BI) {
-+              status &= ~(UART_LSR_FE);
-+              port->icount.brk++;
-+
-+#ifdef SUPPORT_SYSRQ
-+              if (uart_handle_break(port))
-+                      goto ignore_char;
-+#endif
-+      } else if (status & UART_LSR_PE)
-+              port->icount.parity++;
-+      else if (status & UART_LSR_FE)
-+              port->icount.frame++;
-+
-+      if (status & UART_LSR_OE)
-+              port->icount.overrun++;
-+
-+      if (status & port->ignore_status_mask) {
-+              if (++ignored > 100)
-+                      goto out;
-+              goto ignore_char;
-+      }
-+
-+      mask = status & port->read_status_mask;
-+
-+      if (mask & UART_LSR_BI)
-+              flg = TTY_BREAK;
-+      else if (mask & UART_LSR_PE)
-+              flg = TTY_PARITY;
-+      else if (mask & UART_LSR_FE)
-+              flg = TTY_FRAME;
-+
-+      if (status & UART_LSR_OE) {
-+              /*
-+               * CHECK: does overrun affect the current character?
-+               * ASSUMPTION: it does not.
-+               */
-+              //*tty->flip.flag_buf_ptr++ = flg;
-+              //*tty->flip.char_buf_ptr++ = ch;
-+              //tty->flip.count++;
-+
-+              tty_insert_flip_char(tty, 0, TTY_BREAK);
-+
-+              // if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+              if (tty_buffer_request_room(tty, 1))
-+                      goto ignore_char;
-+              ch = 0;
-+              flg = TTY_OVERRUN;
-+      }
-+#ifdef SUPPORT_SYSRQ
-+      port->sysrq = 0;
-+#endif
-+      goto error_return;
-+}
-+
-+static void sl2312_tx_chars(struct uart_port *port)
-+{
-+      struct circ_buf *xmit = &port->info->xmit;
-+      int count;
-+
-+
-+      if (port->x_char) {
-+              while(!(UART_GET_LSR(port)&UART_LSR_THRE));
-+              UART_PUT_CHAR(port, port->x_char);
-+              port->icount.tx++;
-+              port->x_char = 0;
-+
-+              return;
-+      }
-+      if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-+              sl2312_stop_tx(port);
-+
-+              return;
-+      }
-+
-+      count = port->fifosize >> 1;
-+      do {
-+              while(!(UART_GET_LSR(port)&UART_LSR_THRE));
-+              UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
-+              xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+              port->icount.tx++;
-+              if (uart_circ_empty(xmit))
-+                      break;
-+      } while (--count > 0);
-+
-+      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+              uart_write_wakeup(port);
-+
-+      if (uart_circ_empty(xmit))
-+              sl2312_stop_tx(port);
-+
-+}
-+
-+static void sl2312_start_tx(struct uart_port *port)
-+{
-+        unsigned int reg;
-+
-+//        printk("sl2312 start tx : \n");
-+        reg = UART_GET_IER(port);
-+        reg |= (UART_IER_TE);
-+      UART_PUT_IER(port, reg);
-+
-+      sl2312_tx_chars(port);
-+}
-+
-+static void sl2312_modem_status(struct uart_port *port)
-+{
-+      unsigned int status;
-+
-+//        printk("it8712 modem status : \n");
-+
-+      status = UART_GET_MSR(port);
-+
-+      if (!(status & (UART_MSR_DCTS | UART_MSR_DDSR |
-+                     UART_MSR_TERI | UART_MSR_DDCD)))
-+              return;
-+
-+        if (status & UART_MSR_DDCD)
-+                uart_handle_dcd_change(port, status & UART_MSR_DCD);
-+
-+        if (status & UART_MSR_DDSR)
-+                port->icount.dsr++;
-+
-+        if (status & UART_MSR_DCTS)
-+                uart_handle_cts_change(port, status & UART_MSR_CTS);
-+
-+      wake_up_interruptible(&port->info->delta_msr_wait);
-+
-+}
-+
-+static irqreturn_t sl2312_int(int irq, void *dev_id)
-+{
-+      struct uart_port *port = dev_id;
-+      unsigned int status, pass_counter = 0;
-+
-+      status = UART_GET_INT_STATUS(port);
-+      do {
-+              switch(status)
-+              {
-+                 case UART_IIR_DR:
-+                 case UART_IIR_RLS:
-+                      sl2312_rx_chars(port);
-+                 break;
-+                 case UART_IIR_TE:
-+                      sl2312_tx_chars(port);
-+                 break;
-+                 case UART_IIR_MODEM:
-+                      sl2312_modem_status(port);
-+                 break;
-+                 default:
-+                 break;
-+              }
-+              if (pass_counter++ > SL2312_ISR_PASS_LIMIT)
-+                      break;
-+
-+              status = UART_GET_INT_STATUS(port);
-+      } while (status);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+static u_int sl2312_tx_empty(struct uart_port *port)
-+{
-+//        printk("sl2312 tx empty : \n");
-+
-+      return ((UART_GET_LSR(port) & UART_LSR_TE)? TIOCSER_TEMT : 0);
-+}
-+
-+static u_int sl2312_get_mctrl(struct uart_port *port)
-+{
-+      unsigned int result = 0;
-+      unsigned int status;
-+
-+//        printk("sl2312 get mctrl : \n");
-+
-+      status = UART_GET_MSR(port);
-+      if (status & UART_MSR_DCD)
-+              result |= TIOCM_CAR;
-+      if (status & UART_MSR_DSR)
-+              result |= TIOCM_DSR;
-+      if (status & UART_MSR_CTS)
-+              result |= TIOCM_CTS;
-+      if (status & UART_MSR_RI)
-+              result |= TIOCM_RI;
-+
-+      return result;
-+}
-+
-+static void sl2312_set_mctrl_null(struct uart_port *port, u_int mctrl)
-+{
-+}
-+
-+static void sl2312_break_ctl(struct uart_port *port, int break_state)
-+{
-+      unsigned int lcr;
-+
-+//        printk("sl2312 break ctl : \n");
-+
-+      lcr = UART_GET_LCR(port);
-+      if (break_state == -1)
-+              lcr |= UART_LCR_SETBREAK;
-+      else
-+              lcr &= ~UART_LCR_SETBREAK;
-+      UART_PUT_LCR(port, lcr);
-+}
-+
-+static inline u_int uart_calculate_quot(struct uart_port *port, u_int baud)
-+{
-+      u_int quot;
-+
-+      /* Special case: B0 rate */
-+      if (!baud)
-+              baud = 9600;
-+
-+      quot = (port->uartclk / (16 * baud)-1)  ;
-+
-+      return quot;
-+}
-+
-+static void sl2312_set_termios(struct uart_port *port, struct ktermios *termios,
-+                               struct ktermios *old)
-+{
-+      unsigned int  uart_mc, old_ier, baud, quot;
-+      unsigned long flags;
-+
-+        termios->c_cflag |= CREAD;
-+#ifdef DEBUG
-+      printk("it8712_set_cflag(0x%x) called\n", cflag);
-+#endif
-+        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
-+        quot = (port->uartclk / (16 * baud))  ;
-+        //uart_get_divisor(port, baud);
-+
-+      /* byte size and parity */
-+      switch (termios->c_cflag & CSIZE) {
-+      case CS5:
-+              uart_mc = UART_LCR_LEN5;
-+              break;
-+      case CS6:
-+              uart_mc = UART_LCR_LEN6;
-+              break;
-+      case CS7:
-+              uart_mc = UART_LCR_LEN7;
-+              break;
-+      default: // CS8
-+              uart_mc = UART_LCR_LEN8;
-+              break;
-+      }
-+
-+      if (termios->c_cflag & CSTOPB)
-+              uart_mc|= UART_LCR_STOP;
-+      if (termios->c_cflag & PARENB) {
-+              uart_mc |= UART_LCR_EVEN;
-+              if (!(termios->c_cflag & PARODD))
-+                      uart_mc |= UART_LCR_ODD;
-+      }
-+
-+    spin_lock_irqsave(&port->lock, flags);
-+        /*
-+         * Update the per-port timeout
-+         */
-+        uart_update_timeout(port, termios->c_cflag, baud);
-+      port->read_status_mask = UART_LSR_OE;
-+      if (termios->c_iflag & INPCK)
-+              port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-+      if (termios->c_iflag & (BRKINT | PARMRK))
-+              port->read_status_mask |= UART_LSR_BI;
-+
-+      /*
-+       * Characters to ignore
-+       */
-+      port->ignore_status_mask = 0;
-+      if (termios->c_iflag & IGNPAR)
-+              port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
-+      if (termios->c_iflag & IGNBRK) {
-+              port->ignore_status_mask |= UART_LSR_BI;
-+              /*
-+               * If we're ignoring parity and break indicators,
-+               * ignore overruns to (for real raw support).
-+               */
-+              if (termios->c_iflag & IGNPAR)
-+                      port->ignore_status_mask |= UART_LSR_OE;
-+      }
-+
-+      //save_flags(flags); cli();
-+      old_ier = UART_GET_IER(port);
-+
-+        if(UART_ENABLE_MS(port, termios->c_cflag))
-+             old_ier |= UART_IER_MS;
-+
-+      /* Set baud rate */
-+      UART_PUT_LCR(port, UART_LCR_DLAB);
-+      UART_PUT_DIV_LO(port, (quot & 0xff));
-+      UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
-+
-+      UART_PUT_LCR(port, uart_mc);
-+      UART_PUT_IER(port, old_ier);
-+
-+      //restore_flags(flags);
-+      spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+
-+
-+static int sl2312_startup(struct uart_port *port)
-+{
-+      int retval;
-+      unsigned int regs;
-+
-+//        printk("sl2312 startup : \n");
-+
-+      /*
-+       * Use iobase to store a pointer to info. We need this to start a
-+       * transmission as the tranmittr interrupt is only generated on
-+       * the transition to the idle state
-+       */
-+
-+      /*
-+       * Allocate the IRQ
-+       */
-+      retval = request_irq(port->irq, sl2312_int, IRQF_DISABLED, "sl2312", port);
-+      if (retval)
-+              return retval;
-+
-+        /* setup interrupt controller  */
-+        regs = *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
-+        regs &= ~(IRQ_UART_MASK);
-+        *((volatile unsigned int *)IRQ_TMODE(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = regs;
-+        regs = *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE)));
-+        regs &= ~(IRQ_UART_MASK);
-+        *((volatile unsigned int *)IRQ_TLEVEL(IO_ADDRESS(SL2312_INTERRUPT_BASE))) = regs;
-+        *((volatile unsigned int *)IRQ_MASK(IO_ADDRESS(SL2312_INTERRUPT_BASE))) |= (unsigned int)(IRQ_UART_MASK);
-+
-+      /*
-+       * Finally, enable interrupts. Use the TII interrupt to minimise
-+       * the number of interrupts generated. If higher performance is
-+       * needed, consider using the TI interrupt with a suitable FIFO
-+       * threshold
-+       */
-+      UART_PUT_IER(port, (UART_IER_DR|UART_IER_TE));
-+
-+      return 0;
-+}
-+
-+static void sl2312_shutdown(struct uart_port *port)
-+{
-+//        printk("sl2312 shutdown : \n");
-+
-+      /*
-+       * disable all interrupts, disable the port
-+       */
-+      UART_PUT_IER(port, 0x0);
-+
-+      /* disable break condition and fifos */
-+//    UART_PUT_MCR(port, (UART_GET_MCR(port)&UART_MCR_MASK));
-+
-+      /*
-+       * Free the interrupt
-+       */
-+      free_irq(port->irq, port);
-+}
-+
-+static const char *sl2312_type(struct uart_port *port)
-+{
-+      return port->type == PORT_SL2312 ? "SL2312" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'
-+ */
-+static void sl2312_release_port(struct uart_port *port)
-+{
-+//        printk("sl2312 release port : \n");
-+
-+      release_mem_region(port->mapbase, UART_PORT_SIZE);
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'
-+ */
-+static int sl2312_request_port(struct uart_port *port)
-+{
-+      return request_mem_region(port->mapbase, UART_PORT_SIZE,
-+                                  "serial_sl2312") != NULL ? 0 : -EBUSY;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void sl2312_config_port(struct uart_port *port, int flags)
-+{
-+
-+      if (flags & UART_CONFIG_TYPE) {
-+              if (sl2312_request_port(port) == 0)
-+                      port->type = PORT_SL2312;
-+      }
-+}
-+
-+/*
-+ * verify the new serial_struct (for TIOCSSERIAL).
-+ */
-+static int sl2312_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+      int ret = 0;
-+
-+      if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
-+              ret = -EINVAL;
-+      if (ser->irq < 0 || ser->irq >= NR_IRQS)
-+              ret = -EINVAL;
-+      if (ser->baud_base < 9600)
-+              ret = -EINVAL;
-+      return ret;
-+}
-+
-+static struct uart_ops sl2312_pops = {
-+      .tx_empty               =sl2312_tx_empty,
-+      .set_mctrl              =sl2312_set_mctrl_null,
-+      .get_mctrl              =sl2312_get_mctrl,
-+      .stop_tx                =sl2312_stop_tx,
-+      .start_tx               =sl2312_start_tx,
-+      .stop_rx                =sl2312_stop_rx,
-+      .enable_ms              =sl2312_enable_ms,
-+      .break_ctl              =sl2312_break_ctl,
-+      .startup                =sl2312_startup,
-+      .shutdown               =sl2312_shutdown,
-+      .set_termios    =sl2312_set_termios,
-+      .type                   =sl2312_type,
-+      .release_port   =sl2312_release_port,
-+      .request_port   =sl2312_request_port,
-+      .config_port    =sl2312_config_port,
-+      .verify_port    =sl2312_verify_port,
-+};
-+
-+#ifdef CONFIG_ARCH_SL2312
-+
-+static struct uart_port sl2312_ports[UART_NR] = {
-+      {
-+              membase:        (void *)IO_ADDRESS(SL2312_UART_BASE),
-+              mapbase:        SL2312_UART_BASE,
-+              iotype:         SERIAL_IO_MEM,
-+              irq:            IRQ_UART,
-+              uartclk:        UART_CLK,
-+              fifosize:       16,
-+              ops:            &sl2312_pops,
-+              flags:          ASYNC_BOOT_AUTOCONF,
-+      }
-+};
-+
-+#endif
-+
-+#ifdef CONFIG_SERIAL_SL2312_CONSOLE
-+#ifdef used_and_not_const_char_pointer
-+static int sl2312_console_read(struct uart_port *port, char *s, u_int count)
-+{
-+      unsigned int status;
-+      int c;
-+#ifdef DEBUG
-+      printk("sl2312_console_read() called\n");
-+#endif
-+
-+      c = 0;
-+      while (c < count) {
-+              status = UART_GET_LSR(port);
-+              if (UART_RX_DATA(status)) {
-+                      *s++ = UART_GET_CHAR(port);
-+                      c++;
-+              } else {
-+                      // nothing more to get, return
-+                      return c;
-+              }
-+      }
-+      // return the count
-+      return c;
-+}
-+#endif
-+static void sl2312_console_write(struct console *co, const char *s, unsigned count)
-+{
-+#ifdef CONFIG_ARCH_SL2312
-+      struct uart_port *port = sl2312_ports + co->index;
-+      unsigned int status, old_ies;
-+      int i;
-+
-+      /*
-+       *      First save the CR then disable the interrupts
-+       */
-+      old_ies = UART_GET_IER(port);
-+      UART_PUT_IER(port,0x0);
-+
-+      /*
-+       *      Now, do each character
-+       */
-+      for (i = 0; i < count; i++) {
-+              do {
-+                      status = UART_GET_LSR(port);
-+              } while (!UART_TX_READY(status));
-+              UART_PUT_CHAR(port, s[i]);
-+              if (s[i] == '\n') {
-+                      do {
-+                              status = UART_GET_LSR(port);
-+                      } while (!UART_TX_READY(status));
-+                      UART_PUT_CHAR(port, '\r');
-+              }
-+      }
-+
-+      /*
-+       *      Finally, wait for transmitter to become empty
-+       *      and restore the IES
-+       */
-+      do {
-+              status = UART_GET_LSR(port);
-+      } while (!(status&UART_LSR_TE));
-+      UART_PUT_IER(port, old_ies);
-+#endif
-+}
-+
-+#if 0
-+static void sl2312_console_device(struct console *co,int *index)
-+{
-+
-+      struct uart_driver *p = co->data;
-+    *index = co->index;
-+    return p->tty_driver;
-+
-+}
-+#endif
-+
-+static void /*__init*/ sl2312_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+//    printk("sl2312 console get options : \n");
-+
-+      u_int uart_mc, quot;
-+      uart_mc= UART_GET_MCR(port);
-+
-+      *parity = 'n';
-+      if (uart_mc & UART_LCR_PE) {
-+              if (uart_mc & UART_LCR_EVEN)
-+                      *parity = 'e';
-+              else
-+                      *parity = 'o';
-+      }
-+
-+      switch (uart_mc & UART_LCR_MSK){
-+
-+      case UART_LCR_LEN5:
-+              *bits = 5;
-+              break;
-+      case UART_LCR_LEN6:
-+              *bits = 6;
-+              break;
-+      case UART_LCR_LEN7:
-+              *bits = 7;
-+              break;
-+      case UART_LCR_LEN8:
-+              *bits = 8;
-+              break;
-+      }
-+      UART_PUT_MCR(port,UART_LCR_DLAB);
-+      quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
-+      UART_PUT_MCR(port,uart_mc);
-+      *baud = port->uartclk / (16 *quot );
-+}
-+
-+static int __init sl2312_console_setup(struct console *co, char *options)
-+{
-+      struct uart_port *port;
-+      int baud = 19200;
-+      int bits = 8;
-+      int parity = 'n';
-+      int flow= 'n';
-+
-+      printk("sl2312 console setup : \n");
-+
-+#ifdef CONFIG_ARCH_SL2312
-+      /*
-+       * Check whether an invalid uart number has been specified, and
-+       * if so, search for the first available port that does have
-+       * console support.
-+       */
-+      port = uart_get_console(sl2312_ports,SL2312_NO_PORTS,co);
-+#else
-+      return -ENODEV;
-+#endif
-+
-+      if (options)
-+              uart_parse_options(options, &baud, &parity, &bits, &flow);
-+      else
-+              sl2312_console_get_options(port, &baud, &parity, &bits);
-+
-+      return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+extern struct uart_driver sl2312_reg;
-+static struct console sl2312_console = {
-+      .name      = SERIAL_SL2312_NAME,
-+      .write          = sl2312_console_write,
-+      .device         = uart_console_device,
-+//    .device         = sl2312_console_device,
-+      .setup          = sl2312_console_setup,
-+//    .flags          = (CON_PRINTBUFFER|CON_ENABLED),
-+      .flags          = CON_PRINTBUFFER,
-+      .index          = -1,
-+      .data       = &sl2312_reg,
-+};
-+
-+static int __init sl2312_console_init(void)
-+{
-+      register_console(&sl2312_console);
-+      return 0;
-+
-+}
-+
-+console_initcall(sl2312_console_init);
-+
-+#define SL2312_CONSOLE        &sl2312_console
-+#else
-+#define SL2312_CONSOLE        NULL
-+#endif
-+
-+// static
-+struct uart_driver sl2312_reg = {
-+      .owner         = NULL,
-+      .driver_name    = SERIAL_SL2312_NAME,
-+      .dev_name               = SERIAL_SL2312_NAME,
-+      .major          = SERIAL_SL2312_MAJOR,
-+      .minor                  = SERIAL_SL2312_MINOR,
-+      .nr                             = UART_NR,
-+      .cons                   = SL2312_CONSOLE,
-+};
-+
-+static int __init sl2312_init(void)
-+{
-+       int result;
-+      //printk("serial_it8712: it871212_init \n");
-+
-+        result = uart_register_driver(&sl2312_reg);
-+        if(result)
-+             return result;
-+      result = uart_add_one_port(&sl2312_reg, &sl2312_ports[0]);
-+
-+        return result;
-+}
-+
-+
-+__initcall(sl2312_init);
---- a/include/linux/serial_core.h
-+++ b/include/linux/serial_core.h
-@@ -147,6 +147,10 @@
- #define PORT_SB1250_DUART     77
-+/* Storlink Soc */
-+#define PORT_SL2312     72
-+#define PORT_IT8712     73
-+
- #ifdef __KERNEL__
- #include <linux/compiler.h>
---- a/drivers/char/Makefile
-+++ b/drivers/char/Makefile
-@@ -70,6 +70,16 @@ obj-$(CONFIG_R3964)         += n_r3964.o
- obj-$(CONFIG_APPLICOM)                += applicom.o
- obj-$(CONFIG_SONYPI)          += sonypi.o
- obj-$(CONFIG_RTC)             += rtc.o
-+
-+###  for Storlink SoC ###
-+obj-$(CONFIG_SL2312_RTC) += sl2312_rtc.o
-+obj-$(CONFIG_IT8712_GPIO)   += it8712_gpio.o
-+obj-$(CONFIG_GEMINI_GPIO)   += gemini_gpio.o
-+obj-$(CONFIG_GEMINI_PWC) += gemini_pwr.o
-+obj-$(CONFIG_GEMINI_CIR)    += gemini_cir.o
-+obj-$(CONFIG_GEMINI_I2S)    += gemini_i2s.o
-+obj-$(CONFIG_SL2312_WATCHDOG) += sl2312_wd.o
-+
- obj-$(CONFIG_HPET)            += hpet.o
- obj-$(CONFIG_GEN_RTC)         += genrtc.o
- obj-$(CONFIG_EFI_RTC)         += efirtc.o
---- a/drivers/serial/Kconfig
-+++ b/drivers/serial/Kconfig
-@@ -280,6 +280,56 @@ config SERIAL_8250_RM9K
- comment "Non-8250 serial port support"
-+config SERIAL_SL2312
-+      bool "SL2312  serial port (sl2312) support"
-+      depends on ARCH_SL2312
-+      select SERIAL_CORE
-+      select SERIAL_SL2312_CONSOLE
-+      help
-+         Say Y here if you want to use the hard logic uart on SWORD. This
-+         driver also supports soft logic implentations of this uart core.
-+
-+config SERIAL_SL2312_CONSOLE
-+      bool "Support for console on SL2312 serial port"
-+      depends on SERIAL_SL2312
-+      select SERIAL_CORE_CONSOLE
-+      help
-+        Say Y here if you want to support a serial console on an SWORD
-+        hard logic uart or uart00 IP core.
-+
-+        Even if you say Y here, the currently visible virtual console
-+        (/dev/tty0) will still be used as the system console by default, but
-+        you can alter that using a kernel command line option such as
-+        "console=ttyS0". (Try "man bootparam" or see the documentation of
-+        your boot loader (lilo or loadlin) about how to pass options to the
-+        kernel at boot time.)
-+
-+
-+config SERIAL_IT8712
-+      bool "Sl2312 serial port(IT8712) support"
-+      depends on ARM && ARCH_SL2312 && SL2312_LPC
-+      select SERIAL_CORE
-+      select SERIAL_IT8712_CONSOLE
-+      help
-+        Say Y here if you want to use the hard logic uart on Excalibur. This
-+        driver also supports soft logic implentations of this uart core.
-+
-+config SERIAL_IT8712_CONSOLE
-+      bool "Support for console on Sword serial port(IT8712)"
-+      depends on SERIAL_IT8712
-+      select SERIAL_CORE_CONSOLE
-+      help
-+        Say Y here if you want to support a serial console on an Excalibur
-+        hard logic uart or uart00 IP core.
-+
-+        Even if you say Y here, the currently visible virtual console
-+        (/dev/tty0) will still be used as the system console by default, but
-+        you can alter that using a kernel command line option such as
-+        "console=ttySI0". (Try "man bootparam" or see the documentation of
-+        your boot loader (lilo or loadlin) about how to pass options to the
-+        kernel at boot time.)
-+
-+
- config SERIAL_AMBA_PL010
-       tristate "ARM AMBA PL010 serial port support"
-       depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
---- a/drivers/serial/Makefile
-+++ b/drivers/serial/Makefile
-@@ -62,5 +62,7 @@ obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_se
- obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
- obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
- obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
-+obj-$(CONFIG_SERIAL_IT8712) += it8712.o
-+obj-$(CONFIG_SERIAL_SL2312) += serial_sl2312.o
- obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
- obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o