diff options
author | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-06-05 17:14:02 +0000 |
---|---|---|
committer | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-06-05 17:14:02 +0000 |
commit | d57e4d97e77506e9f634eabe6412c57d81ce0bd4 (patch) | |
tree | 6f38cfee0e5539197d6de60dbe72192ab5b518f8 /target/linux/storm/patches/1021-serial.patch | |
parent | f4fb68ce2cd61529703f4244c3126e47ce0cfec4 (diff) |
rename and renumber storm patches
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@11368 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/storm/patches/1021-serial.patch')
-rw-r--r-- | target/linux/storm/patches/1021-serial.patch | 2809 |
1 files changed, 0 insertions, 2809 deletions
diff --git a/target/linux/storm/patches/1021-serial.patch b/target/linux/storm/patches/1021-serial.patch deleted file mode 100644 index b7009af25..000000000 --- a/target/linux/storm/patches/1021-serial.patch +++ /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_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 @@ - - 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_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 |