]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
[ARM] 4332/2: KS8695: Serial driver
authorAndrew Victor <andrew@sanpeople.com>
Fri, 11 May 2007 20:37:25 +0000 (21:37 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 11 May 2007 21:02:52 +0000 (22:02 +0100)
A driver for the KS8695 internal UART.

Based on the 2.6.9 driver from Micrel.

Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/serial_ks8695.c [new file with mode: 0644]
include/linux/serial_core.h

index a6f5bfbb777b646ae75047c3ba625a677ba3edc3..315ea99164566b01458c4a1d676b7b1aa37fdb83 100644 (file)
@@ -359,6 +359,23 @@ config SERIAL_ATMEL_TTYAT
 
          Say Y if you have an external 8250/16C550 UART.  If unsure, say N.
 
+config SERIAL_KS8695
+       bool "Micrel KS8695 (Centaur) serial port support"
+       depends on ARCH_KS8695
+       select SERIAL_CORE
+       help
+         This selects the Micrel Centaur KS8695 UART.  Say Y here.
+
+config SERIAL_KS8695_CONSOLE
+       bool "Support for console on KS8695 (Centaur) serial port"
+       depends on SERIAL_KS8695=y
+       select SERIAL_CORE_CONSOLE
+       help
+         Say Y here if you wish to use a KS8695 (Centaur) UART as the
+         system console (the system console is the device which
+         receives all kernel messages and warnings and which allows
+         logins in single user mode).
+
 config SERIAL_CLPS711X
        tristate "CLPS711X serial port support"
        depends on ARM && ARCH_CLPS711X
index 4959bcb8d1ef056d5cecadff3e9d6612a527a0d1..08ad0d9781838396fe44c180dd31f6ea9d1cab5e 100644 (file)
@@ -61,3 +61,4 @@ obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
 obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_NETX) += netx-serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
+obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
new file mode 100644 (file)
index 0000000..c5346d6
--- /dev/null
@@ -0,0 +1,657 @@
+/*
+ *  drivers/serial/serial_ks8695.c
+ *
+ *  Driver for KS8695 serial ports
+ *
+ *  Based on drivers/serial/serial_amba.c, by Kam Lee.
+ *
+ *  Copyright 2002-2005 Micrel Inc.
+ *
+ * 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.
+ *
+ */
+#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 <linux/device.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-uart.h>
+#include <asm/arch/regs-irq.h>
+
+#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+
+#define SERIAL_KS8695_MAJOR    204
+#define SERIAL_KS8695_MINOR    16
+#define SERIAL_KS8695_DEVNAME  "ttyAM"
+
+#define SERIAL_KS8695_NR       1
+
+/*
+ * Access macros for the KS8695 UART
+ */
+#define UART_GET_CHAR(p)       (__raw_readl((p)->membase + KS8695_URRB) & 0xFF)
+#define UART_PUT_CHAR(p, c)    __raw_writel((c), (p)->membase + KS8695_URTH)
+#define UART_GET_FCR(p)                __raw_readl((p)->membase + KS8695_URFC)
+#define UART_PUT_FCR(p, c)     __raw_writel((c), (p)->membase + KS8695_URFC)
+#define UART_GET_MSR(p)                __raw_readl((p)->membase + KS8695_URMS)
+#define UART_GET_LSR(p)                __raw_readl((p)->membase + KS8695_URLS)
+#define UART_GET_LCR(p)                __raw_readl((p)->membase + KS8695_URLC)
+#define UART_PUT_LCR(p, c)     __raw_writel((c), (p)->membase + KS8695_URLC)
+#define UART_GET_MCR(p)                __raw_readl((p)->membase + KS8695_URMC)
+#define UART_PUT_MCR(p, c)     __raw_writel((c), (p)->membase + KS8695_URMC)
+#define UART_GET_BRDR(p)       __raw_readl((p)->membase + KS8695_URBD)
+#define UART_PUT_BRDR(p, c)    __raw_writel((c), (p)->membase + KS8695_URBD)
+
+#define KS8695_CLR_TX_INT()    __raw_writel(1 << KS8695_IRQ_UART_TX, KS8695_IRQ_VA + KS8695_INTST)
+
+#define UART_DUMMY_LSR_RX      0x100
+#define UART_PORT_SIZE         (KS8695_USR - KS8695_URRB + 4)
+
+#define tx_enabled(port) ((port)->unused[0])
+#define rx_enabled(port) ((port)->unused[1])
+
+
+#ifdef SUPPORT_SYSRQ
+static struct console ks8695_console;
+#endif
+
+static void ks8695uart_stop_tx(struct uart_port *port)
+{
+       if (tx_enabled(port)) {
+               disable_irq(KS8695_IRQ_UART_TX);
+               tx_enabled(port) = 0;
+       }
+}
+
+static void ks8695uart_start_tx(struct uart_port *port)
+{
+       if (!tx_enabled(port)) {
+               enable_irq(KS8695_IRQ_UART_TX);
+               tx_enabled(port) = 1;
+       }
+}
+
+static void ks8695uart_stop_rx(struct uart_port *port)
+{
+       if (rx_enabled(port)) {
+               disable_irq(KS8695_IRQ_UART_RX);
+               rx_enabled(port) = 0;
+       }
+}
+
+static void ks8695uart_enable_ms(struct uart_port *port)
+{
+       enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+}
+
+static void ks8695uart_disable_ms(struct uart_port *port)
+{
+       disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+}
+
+static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
+{
+       struct uart_port *port = dev_id;
+       struct tty_struct *tty = port->info->tty;
+       unsigned int status, ch, lsr, flg, max_count = 256;
+
+       status = UART_GET_LSR(port);            /* clears pending LSR interrupts */
+       while ((status & URLS_URDR) && max_count--) {
+               ch = UART_GET_CHAR(port);
+               flg = TTY_NORMAL;
+
+               port->icount.rx++;
+
+               /*
+                * Note that the error handling code is
+                * out of the main execution path
+                */
+               lsr = UART_GET_LSR(port) | UART_DUMMY_LSR_RX;
+               if (unlikely(lsr & (URLS_URBI | URLS_URPE | URLS_URFE | URLS_URROE))) {
+                       if (lsr & URLS_URBI) {
+                               lsr &= ~(URLS_URFE | URLS_URPE);
+                               port->icount.brk++;
+                               if (uart_handle_break(port))
+                                       goto ignore_char;
+                       }
+                       if (lsr & URLS_URPE)
+                               port->icount.parity++;
+                       if (lsr & URLS_URFE)
+                               port->icount.frame++;
+                       if (lsr & URLS_URROE)
+                               port->icount.overrun++;
+
+                       lsr &= port->read_status_mask;
+
+                       if (lsr & URLS_URBI)
+                               flg = TTY_BREAK;
+                       else if (lsr & URLS_URPE)
+                               flg = TTY_PARITY;
+                       else if (lsr & URLS_URFE)
+                               flg = TTY_FRAME;
+               }
+
+               if (uart_handle_sysrq_char(port, ch))
+                       goto ignore_char;
+
+               uart_insert_char(port, lsr, URLS_URROE, ch, flg);
+
+ignore_char:
+               status = UART_GET_LSR(port);
+       }
+       tty_flip_buffer_push(tty);
+
+       return IRQ_HANDLED;
+}
+
+
+static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id)
+{
+       struct uart_port *port = dev_id;
+       struct circ_buf *xmit = &port->info->xmit;
+       unsigned int count;
+
+       if (port->x_char) {
+               KS8695_CLR_TX_INT();
+               UART_PUT_CHAR(port, port->x_char);
+               port->icount.tx++;
+               port->x_char = 0;
+               return IRQ_HANDLED;
+       }
+
+       if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
+               ks8695uart_stop_tx(port);
+               return IRQ_HANDLED;
+       }
+
+       count = 16;     /* fifo size */
+       while (!uart_circ_empty(xmit) && (count-- > 0)) {
+               KS8695_CLR_TX_INT();
+               UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
+
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               port->icount.tx++;
+       }
+
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+
+       if (uart_circ_empty(xmit))
+               ks8695uart_stop_tx(port);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t ks8695uart_modem_status(int irq, void *dev_id)
+{
+       struct uart_port *port = dev_id;
+       unsigned int status;
+
+       /*
+        * clear modem interrupt by reading MSR
+        */
+       status = UART_GET_MSR(port);
+
+       if (status & URMS_URDDCD)
+               uart_handle_dcd_change(port, status & URMS_URDDCD);
+
+       if (status & URMS_URDDST)
+               port->icount.dsr++;
+
+       if (status & URMS_URDCTS)
+               uart_handle_cts_change(port, status & URMS_URDCTS);
+
+       if (status & URMS_URTERI)
+               port->icount.rng++;
+
+       wake_up_interruptible(&port->info->delta_msr_wait);
+
+       return IRQ_HANDLED;
+}
+
+static unsigned int ks8695uart_tx_empty(struct uart_port *port)
+{
+       return (UART_GET_LSR(port) & URLS_URTE) ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int ks8695uart_get_mctrl(struct uart_port *port)
+{
+       unsigned int result = 0;
+       unsigned int status;
+
+       status = UART_GET_MSR(port);
+       if (status & URMS_URDCD)
+               result |= TIOCM_CAR;
+       if (status & URMS_URDSR)
+               result |= TIOCM_DSR;
+       if (status & URMS_URCTS)
+               result |= TIOCM_CTS;
+       if (status & URMS_URRI)
+               result |= TIOCM_RI;
+
+       return result;
+}
+
+static void ks8695uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+       unsigned int mcr;
+
+       mcr = UART_GET_MCR(port);
+       if (mctrl & TIOCM_RTS)
+               mcr |= URMC_URRTS;
+       else
+               mcr &= ~URMC_URRTS;
+
+       if (mctrl & TIOCM_DTR)
+               mcr |= URMC_URDTR;
+       else
+               mcr &= ~URMC_URDTR;
+
+       UART_PUT_MCR(port, mcr);
+}
+
+static void ks8695uart_break_ctl(struct uart_port *port, int break_state)
+{
+       unsigned int lcr;
+
+       lcr = UART_GET_LCR(port);
+
+       if (break_state == -1)
+               lcr |= URLC_URSBC;
+       else
+               lcr &= ~URLC_URSBC;
+
+       UART_PUT_LCR(port, lcr);
+}
+
+static int ks8695uart_startup(struct uart_port *port)
+{
+       int retval;
+
+       set_irq_flags(KS8695_IRQ_UART_TX, IRQF_VALID | IRQF_NOAUTOEN);
+       tx_enabled(port) = 0;
+       rx_enabled(port) = 1;
+
+       /*
+        * Allocate the IRQ
+        */
+       retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, IRQF_DISABLED, "UART TX", port);
+       if (retval)
+               goto err_tx;
+
+       retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, IRQF_DISABLED, "UART RX", port);
+       if (retval)
+               goto err_rx;
+
+       retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, IRQF_DISABLED, "UART LineStatus", port);
+       if (retval)
+               return err_ls;
+
+       retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, IRQF_DISABLED, "UART ModemStatus", port);
+       if (retval)
+               return err_ms;
+
+       return 0;
+
+err_ms:
+       free_irq(KS8695_IRQ_UART_LINE_STATUS, port);
+err_ls:
+       free_irq(KS8695_IRQ_UART_RX, port);
+err_rx:
+       free_irq(KS8695_IRQ_UART_TX, port);
+err_tx:
+       return retval;
+}
+
+static void ks8695uart_shutdown(struct uart_port *port)
+{
+       /*
+        * Free the interrupt
+        */
+       free_irq(KS8695_IRQ_UART_RX, port);
+       free_irq(KS8695_IRQ_UART_TX, port);
+       free_irq(KS8695_IRQ_UART_MODEM_STATUS, port);
+       free_irq(KS8695_IRQ_UART_LINE_STATUS, port);
+
+       /* disable break condition and fifos */
+       UART_PUT_LCR(port, UART_GET_LCR(port) & ~URLC_URSBC);
+       UART_PUT_FCR(port, UART_GET_FCR(port) & ~URFC_URFE);
+}
+
+static void ks8695uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old)
+{
+       unsigned int lcr, fcr = 0;
+       unsigned long flags;
+       unsigned int baud, quot;
+
+       /*
+        * Ask the core to calculate the divisor for us.
+        */
+       baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+       quot = uart_get_divisor(port, baud);
+
+       switch (termios->c_cflag & CSIZE) {
+       case CS5:
+               lcr = URCL_5;
+               break;
+       case CS6:
+               lcr = URCL_6;
+               break;
+       case CS7:
+               lcr = URCL_7;
+               break;
+       default:
+               lcr = URCL_8;
+               break;
+       }
+
+       /* stop bits */
+       if (termios->c_cflag & CSTOPB)
+               lcr |= URLC_URSB;
+
+       /* parity */
+       if (termios->c_cflag & PARENB) {
+               if (termios->c_cflag & CMSPAR) {        /* Mark or Space parity */
+                       if (termios->c_cflag & PARODD)
+                               lcr |= URPE_MARK;
+                       else
+                               lcr |= URPE_SPACE;
+               }
+               else if (termios->c_cflag & PARODD)
+                       lcr |= URPE_ODD;
+               else
+                       lcr |= URPE_EVEN;
+       }
+
+       if (port->fifosize > 1)
+               fcr = URFC_URFRT_8 | URFC_URTFR | URFC_URRFR | URFC_URFE;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       /*
+        * Update the per-port timeout.
+        */
+       uart_update_timeout(port, termios->c_cflag, baud);
+
+       port->read_status_mask = URLS_URROE;
+       if (termios->c_iflag & INPCK)
+               port->read_status_mask |= (URLS_URFE | URLS_URPE);
+       if (termios->c_iflag & (BRKINT | PARMRK))
+               port->read_status_mask |= URLS_URBI;
+
+       /*
+        * Characters to ignore
+        */
+       port->ignore_status_mask = 0;
+       if (termios->c_iflag & IGNPAR)
+               port->ignore_status_mask |= (URLS_URFE | URLS_URPE);
+       if (termios->c_iflag & IGNBRK) {
+               port->ignore_status_mask |= URLS_URBI;
+               /*
+                * If we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if (termios->c_iflag & IGNPAR)
+                       port->ignore_status_mask |= URLS_URROE;
+       }
+
+       /*
+        * Ignore all characters if CREAD is not set.
+        */
+       if ((termios->c_cflag & CREAD) == 0)
+               port->ignore_status_mask |= UART_DUMMY_LSR_RX;
+
+       /* first, disable everything */
+       if (UART_ENABLE_MS(port, termios->c_cflag))
+               ks8695uart_enable_ms(port);
+       else
+               ks8695uart_disable_ms(port);
+
+       /* Set baud rate */
+       UART_PUT_BRDR(port, quot);
+
+       UART_PUT_LCR(port, lcr);
+       UART_PUT_FCR(port, fcr);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *ks8695uart_type(struct uart_port *port)
+{
+       return port->type == PORT_KS8695 ? "KS8695" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void ks8695uart_release_port(struct uart_port *port)
+{
+       release_mem_region(port->mapbase, UART_PORT_SIZE);
+}
+
+/*
+ * Request the memory region(s) being used by 'port'
+ */
+static int ks8695uart_request_port(struct uart_port *port)
+{
+       return request_mem_region(port->mapbase, UART_PORT_SIZE,
+                       "serial_ks8695") != NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void ks8695uart_config_port(struct uart_port *port, int flags)
+{
+       if (flags & UART_CONFIG_TYPE) {
+               port->type = PORT_KS8695;
+               ks8695uart_request_port(port);
+       }
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int ks8695uart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+       int ret = 0;
+
+       if (ser->type != PORT_UNKNOWN && ser->type != PORT_KS8695)
+               ret = -EINVAL;
+       if (ser->irq != port->irq)
+               ret = -EINVAL;
+       if (ser->baud_base < 9600)
+               ret = -EINVAL;
+       return ret;
+}
+
+static struct uart_ops ks8695uart_pops = {
+       .tx_empty       = ks8695uart_tx_empty,
+       .set_mctrl      = ks8695uart_set_mctrl,
+       .get_mctrl      = ks8695uart_get_mctrl,
+       .stop_tx        = ks8695uart_stop_tx,
+       .start_tx       = ks8695uart_start_tx,
+       .stop_rx        = ks8695uart_stop_rx,
+       .enable_ms      = ks8695uart_enable_ms,
+       .break_ctl      = ks8695uart_break_ctl,
+       .startup        = ks8695uart_startup,
+       .shutdown       = ks8695uart_shutdown,
+       .set_termios    = ks8695uart_set_termios,
+       .type           = ks8695uart_type,
+       .release_port   = ks8695uart_release_port,
+       .request_port   = ks8695uart_request_port,
+       .config_port    = ks8695uart_config_port,
+       .verify_port    = ks8695uart_verify_port,
+};
+
+static struct uart_port ks8695uart_ports[SERIAL_KS8695_NR] = {
+       {
+               .membase        = (void *) KS8695_UART_VA,
+               .mapbase        = KS8695_UART_VA,
+               .iotype         = SERIAL_IO_MEM,
+               .irq            = KS8695_IRQ_UART_TX,
+               .uartclk        = CLOCK_TICK_RATE * 16,
+               .fifosize       = 16,
+               .ops            = &ks8695uart_pops,
+               .flags          = ASYNC_BOOT_AUTOCONF,
+               .line           = 0,
+       }
+};
+
+#ifdef CONFIG_SERIAL_KS8695_CONSOLE
+static void ks8695_console_putchar(struct uart_port *port, int ch)
+{
+       while (!(UART_GET_LSR(port) & URLS_URTHRE))
+               barrier();
+
+       UART_PUT_CHAR(port, ch);
+}
+
+static void ks8695_console_write(struct console *co, const char *s, u_int count)
+{
+       struct uart_port *port = ks8695uart_ports + co->index;
+
+       uart_console_write(port, s, count, ks8695_console_putchar);
+}
+
+static void __init ks8695_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
+{
+       unsigned int lcr;
+
+       lcr = UART_GET_LCR(port);
+
+       switch (lcr & URLC_PARITY) {
+               case URPE_ODD:
+                       *parity = 'o';
+                       break;
+               case URPE_EVEN:
+                       *parity = 'e';
+                       break;
+               default:
+                       *parity = 'n';
+       }
+
+       switch (lcr & URLC_URCL) {
+               case URCL_5:
+                       *bits = 5;
+                       break;
+               case URCL_6:
+                       *bits = 6;
+                       break;
+               case URCL_7:
+                       *bits = 7;
+                       break;
+               default:
+                       *bits = 8;
+       }
+
+       *baud = port->uartclk / (UART_GET_BRDR(port) & 0x0FFF);
+       *baud /= 16;
+       *baud &= 0xFFFFFFF0;
+}
+
+static int __init ks8695_console_setup(struct console *co, char *options)
+{
+       struct uart_port *port;
+       int baud = 115200;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+
+       /*
+        * 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(ks8695uart_ports, SERIAL_KS8695_NR, co);
+
+       if (options)
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+       else
+               ks8695_console_get_options(port, &baud, &parity, &bits);
+
+       return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+extern struct uart_driver ks8695_reg;
+
+static struct console ks8695_console = {
+       .name           = SERIAL_KS8695_DEVNAME,
+       .write          = ks8695_console_write,
+       .device         = uart_console_device,
+       .setup          = ks8695_console_setup,
+       .flags          = CON_PRINTBUFFER,
+       .index          = -1,
+       .data           = &ks8695_reg,
+};
+
+static int __init ks8695_console_init(void)
+{
+       register_console(&ks8695_console);
+       return 0;
+}
+
+console_initcall(ks8695_console_init);
+
+#define KS8695_CONSOLE &ks8695_console
+#else
+#define KS8695_CONSOLE NULL
+#endif
+
+static struct uart_driver ks8695_reg = {
+       .owner                  = THIS_MODULE,
+       .driver_name            = "serial_ks8695",
+       .dev_name               = SERIAL_KS8695_DEVNAME,
+       .major                  = SERIAL_KS8695_MAJOR,
+       .minor                  = SERIAL_KS8695_MINOR,
+       .nr                     = SERIAL_KS8695_NR,
+       .cons                   = KS8695_CONSOLE,
+};
+
+static int __init ks8695uart_init(void)
+{
+       int i, ret;
+
+       printk(KERN_INFO "Serial: Micrel KS8695 UART driver\n");
+
+       ret = uart_register_driver(&ks8695_reg);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < SERIAL_KS8695_NR; i++)
+               uart_add_one_port(&ks8695_reg, &ks8695uart_ports[0]);
+
+       return 0;
+}
+
+static void __exit ks8695uart_exit(void)
+{
+       int i;
+
+       for (i = 0; i < SERIAL_KS8695_NR; i++)
+               uart_remove_one_port(&ks8695_reg, &ks8695uart_ports[0]);
+       uart_unregister_driver(&ks8695_reg);
+}
+
+module_init(ks8695uart_init);
+module_exit(ks8695uart_exit);
+
+MODULE_DESCRIPTION("KS8695 serial port driver");
+MODULE_AUTHOR("Micrel Inc.");
+MODULE_LICENSE("GPL");
index aa2653a159f4332e25b8e0b0da0b78b4be68019f..a3ac4c8968312b1173903ccd7caa890c56ae01bc 100644 (file)
 /* Blackfin bf5xx */
 #define PORT_BFIN      75
 
+/* Micrel KS8695 */
+#define PORT_KS8695    76
+
+
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>