diff -urN -X /home/arm/dontdiff_tml_arm /home/download/kernels/linux-2.4.19-rmk2-vanilla/drivers/serial/serial_psionw.c linux-2.4.19-rmk2/drivers/serial/serial_psionw.c
diff -urN -X /home/arm/dontdiff_tml_arm /home/download/kernels/linux-2.4.19-rmk2-vanilla/drivers/serial/serial_psionw.c linux-2.4.19-rmk2/drivers/serial/serial_psionw.c
--- /home/download/kernels/linux-2.4.19-rmk2-vanilla/drivers/serial/serial_psionw.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.19-rmk2/drivers/serial/serial_psionw.c	2002-10-06 14:19:37.000000000 -0700
@@ -0,0 +1,789 @@
+/*
+ *  linux/drivers/char/serial_psionw.c
+ *
+ *  Copyright (C) 2001 Yuji Shinokawa <ysh@mob.or.jp>
+ *
+ *  Written by Yuji Shinokawa, Irda port support and generic 
+ *  updates by Tony Lindgren <tony@atomide.com>
+ *
+ *  Based on the clps711x code, some portions of the code
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * 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
+ */
+#include <linux/config.h>
+#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>
+
+#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+#include "serial_psionw.h"
+
+#define UART_NR		2
+
+#define SERIAL_PSIONW_NAME	"ttyAM"
+#define SERIAL_PSIONW_MAJOR	204
+#define SERIAL_PSIONW_MINOR	16
+#define SERIAL_PSIONW_NR	UART_NR
+
+#define CALLOUT_PSIONW_NAME	"cuaam"
+#define CALLOUT_PSIONW_MAJOR	205
+#define CALLOUT_PSIONW_MINOR	16
+#define CALLOUT_PSIONW_NR	UART_NR
+
+static struct tty_driver normal, callout;
+static struct tty_struct *psionw_table[UART_NR];
+static struct termios *psionw_termios[UART_NR],*psionw_termios_locked[UART_NR];
+#ifdef SUPPORT_SYSRQ
+static struct console psionw_console;
+#endif
+
+static void
+psionwuart_stop_tx(struct uart_port *port, u_int from_tty)
+{
+	u_int uartintm;
+
+	uartintm = UART_GET_INT_MASK(port);
+	uartintm &= ~PSIONW_UART_TXINT;
+	UART_PUT_INT_MASK(port, uartintm);
+}
+
+static void
+psionwuart_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
+{
+	u_int uartintm;
+
+	if (nonempty) {
+		uartintm = UART_GET_INT_MASK(port);
+		uartintm |= PSIONW_UART_TXINT;
+		UART_PUT_INT_MASK(port, uartintm);
+	}
+}
+
+static void
+psionwuart_stop_rx(struct uart_port *port)
+{
+	u_int uartintm;
+
+	uartintm = UART_GET_INT_MASK(port);
+	uartintm &= ~PSIONW_UART_RXINT;
+	UART_PUT_INT_MASK(port, uartintm);
+}
+
+static void
+psionwuart_enable_ms(struct uart_port *port)
+{
+	u_int uartintm;
+
+	uartintm = UART_GET_INT_MASK(port);
+	uartintm |= PSIONW_UART_MSINT;
+	UART_PUT_INT_MASK(port, uartintm);
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+psionwuart_rx_chars(struct uart_info *info, struct pt_regs *regs)
+#else
+psionwuart_rx_chars(struct uart_info *info)
+#endif
+{
+	struct tty_struct *tty = info->tty;
+	unsigned int status, ch, rsr, max_count = 256;
+	struct uart_port *port = info->port;
+
+	status = UART_GET_FR(port);
+	while (UART_RX_DATA(status) && max_count--) {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *) tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+				return;
+			}
+		}
+
+		/* Get the data plus 3 error bits */
+		rsr = UART_GET_CHAR(port);
+		ch = (rsr & 0xff);
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path.
+		 * Note also that psionw has the error bits
+		 * in the data register.
+		 */
+		//rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
+		//rsr |= UART_DUMMY_RSR_RX;
+		if (rsr & PSIONW_UARTRSR_ANY) {
+			if (rsr & PSIONW_UARTRSR_PE) {
+				port->icount.parity++;
+			} else if (rsr & PSIONW_UARTRSR_FE) {
+				port->icount.frame++;
+			}
+			if (rsr & PSIONW_UARTRSR_OE) {
+				port->icount.overrun++;
+			}
+			rsr &= port->read_status_mask;
+			if (rsr & PSIONW_UARTRSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (rsr & PSIONW_UARTRSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(info, ch, regs))
+			goto ignore_char;
+
+		if ((rsr & port->ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((rsr & PSIONW_UARTRSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			*tty->flip.char_buf_ptr++ = 0;
+			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+			tty->flip.count++;
+		}
+	      ignore_char:
+		status = UART_GET_FR(port);
+	}
+	tty_flip_buffer_push(tty);
+	return;
+}
+
+static void
+psionwuart_tx_chars(struct uart_info *info)
+{
+	struct uart_port *port = info->port;
+	int count;
+	unsigned int status;
+
+	if (port->x_char) {
+		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) {
+		psionwuart_stop_tx(port, 0);
+		return;
+	}
+
+	count = port->fifosize >> 1;
+	do {
+		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)
+		psionwuart_stop_tx(info->port, 0);
+}
+
+static u_int
+psionwuart_tx_empty(struct uart_port *port)
+{
+	u_int status = UART_GET_FR(port);
+	return status & AMBA_UARTFR_BUSY ? 0 : TIOCSER_TEMT;
+}
+
+static int
+psionwuart_get_mctrl(struct uart_port *port)
+{
+	unsigned int result = 0;
+	unsigned int status;
+
+	status = UART_GET_FR(port);
+	if (status & AMBA_UARTFR_DCD)
+		result |= TIOCM_CAR;
+	if (status & AMBA_UARTFR_DSR)
+		result |= TIOCM_DSR;
+	if (status & AMBA_UARTFR_CTS)
+		result |= TIOCM_CTS;
+
+	return result;
+}
+
+static void
+psionwuart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	unsigned int pcdr = 0;
+
+	/* NOTE: printk's here will corrupt the terminal */
+	if ((mctrl & TIOCM_RTS) == TIOCM_RTS) {
+		pcdr = psionw_readl(PCDR);
+		if (port->mapbase == PSIONW_UART0_V_BASE) {
+			pcdr |= PCDR_UART1;
+		} else if (port->mapbase == PSIONW_UART1_V_BASE) {
+			pcdr |= PCDR_UART2;
+		}
+		psionw_writel(pcdr, PCDR);
+	}
+}
+
+static void
+psionwuart_break_ctl(struct uart_port *port, int break_state)
+{
+	unsigned int ubrfcr;
+
+	ubrfcr = UART_GET_FCR(port);
+	if (break_state == -1)
+		ubrfcr |= PSIONW_UARTFCR_BREAK;
+	else
+		ubrfcr &= ~PSIONW_UARTFCR_BREAK;
+	UART_PUT_FCR(port, ubrfcr);
+}
+
+/*
+ * Only used for the UART1, the Irda port does not support this.
+ */
+static void
+psionwuart_modem_status(struct uart_info *info)
+{
+	struct uart_port *port = info->port;
+	unsigned int status, delta;
+
+	status = UART_GET_FR(port) & PSIONW_UARTFR_MODEM_ANY;
+	psionw_writel(0, UMSEOI);
+
+	delta = status ^ info->driver_priv;
+	info->driver_priv = status;
+
+	if (!delta)
+		return;
+
+	if (delta & AMBA_UARTFR_DCD)
+		uart_handle_dcd_change(info, status & AMBA_UARTFR_DCD);
+
+	if (delta & AMBA_UARTFR_DSR)
+		port->icount.dsr++;
+
+	if (delta & AMBA_UARTFR_CTS)
+		uart_handle_cts_change(info, status & AMBA_UARTFR_CTS);
+
+	wake_up_interruptible(&info->delta_msr_wait);
+}
+
+/*
+ * Serial interrupts
+ */
+static void
+psionwuart_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_info *info = dev_id;
+	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
+	unsigned int psionwuart_int_mask = 
+		(PSIONW_UART_RXINT | PSIONW_UART_TXINT | PSIONW_UART_MSINT);
+
+	/* Irda port does not support modem status */
+	if (info->port->mapbase == PSIONW_UART0_V_BASE)
+		psionwuart_int_mask = (PSIONW_UART_RXINT | PSIONW_UART_TXINT);
+
+	status = UART_GET_INT_STATUS(info->port);
+	do {
+		if (status & PSIONW_UART_RXINT) {
+#ifdef SUPPORT_SYSRQ
+			psionwuart_rx_chars(info, regs);
+#else
+			psionwuart_rx_chars(info);
+#endif
+		}
+		if (status & PSIONW_UART_TXINT) {
+			psionwuart_tx_chars(info);
+		}
+		if ((status & PSIONW_UART_MSINT)
+		    && (info->port->mapbase == PSIONW_UART1_V_BASE)) {
+
+			/* Clear modem status interrupt */
+			UART_CLEAR_INT(info->port, 1);
+
+			psionwuart_modem_status(info);
+		}
+		if (pass_counter-- == 0) {
+			break;
+		}
+		status = UART_GET_INT_STATUS(info->port);
+	} while (status & psionwuart_int_mask);
+}
+
+static int
+psionwuart_startup(struct uart_port *port, struct uart_info *info)
+{
+	u_int cfg;
+	int retval;
+	u_int uartintm;
+
+	/*
+	 * Allocate the IRQs
+	 */
+	retval = request_irq(port->irq, psionwuart_int, 0, "psionwuart", info);
+	if (retval)
+		return retval;
+
+	/*
+	 * initialise the old status of the modem signals
+	 */
+	info->driver_priv = UART_GET_FR(port) & PSIONW_UARTFR_MODEM_ANY;
+
+	/*
+	 * enable the port
+	 */
+	UART_PUT_CR(port, PSIONW_UARTCR_UARTEN);
+
+	uartintm = UART_GET_INT_MASK(port);
+	uartintm |= PSIONW_UART_TXINT | PSIONW_UART_RXINT | PSIONW_UART_MSINT;
+	UART_PUT_INT_MASK(port, uartintm);
+
+	// Enable the irda for uart0
+	if (port->mapbase == PSIONW_UART0_V_BASE) {
+		cfg = UART_GET_CR(port);
+		cfg &= ~PSIONW_UARTCR_SIREN;
+		cfg |= PSIONW_UARTCR_IRTXM;	// power friendly tx encoding
+		UART_PUT_CR(port, cfg);
+
+#if 0
+		/*
+		 * Unblock irda rx while tx (full duplex)
+		 * Won't work with IrTTY because of 
+		 * duplicate packets
+		 */
+		cfg = readl(port->membase + PSIONW_UARTTR3);
+		cfg |= PSIONW_UARTTR3_IRUBLOCK;
+		writel(cfg, port->membase + PSIONW_UARTTR3);
+#endif
+
+	}
+
+	return 0;
+}
+
+static void
+psionwuart_shutdown(struct uart_port *port, struct uart_info *info)
+{
+	u_int syscon, pcdr;
+	u_int uartintm;
+
+	/*
+	 * Free the interrupt
+	 */
+	free_irq(port->irq, info);	/* UART interrupt */
+	uartintm = UART_GET_INT_MASK(port);
+	uartintm &= ~(PSIONW_UART_TXINT | PSIONW_UART_RXINT | PSIONW_UART_MSINT);
+	UART_PUT_INT_MASK(port, uartintm);
+
+	/*
+	 * disable the port
+	 */
+	UART_PUT_CR(port, 0);
+
+	/*
+	 * disable break condition and fifos
+	 */
+	UART_PUT_FCR(port, UART_GET_FCR(port) &
+		     ~(PSIONW_UARTFCR_UFIFOEN | PSIONW_UARTFCR_BREAK));
+
+	/*
+	 * Don't forget to disable port in PCDR
+	 */
+	pcdr = psionw_readl(PCDR);
+	if (port->mapbase == PSIONW_UART0_V_BASE) {
+		pcdr &= ~PCDR_UART1;
+	} else if (port->mapbase == PSIONW_UART1_V_BASE) {
+		pcdr &= ~PCDR_UART2;
+	}
+	psionw_writel(pcdr, PCDR);
+
+}
+
+static void
+psionwuart_change_speed(struct uart_port *port, u_int cflag,
+			u_int iflag, u_int quot)
+{
+	u_int fcr;
+	unsigned long flags;
+
+#if DEBUG
+	printk("psionwuart_set_cflag(0x%x) called\n", cflag);
+#endif
+	/* byte size and parity */
+	switch (cflag & CSIZE) {
+	case CS5:
+		fcr = PSIONW_UARTFCR_WLEN_5;
+		break;
+	case CS6:
+		fcr = PSIONW_UARTFCR_WLEN_6;
+		break;
+	case CS7:
+		fcr = PSIONW_UARTFCR_WLEN_7;
+		break;
+	default:
+		fcr = PSIONW_UARTFCR_WLEN_8;
+		break;		// CS8
+	}
+	if (cflag & CSTOPB)
+		fcr |= PSIONW_UARTFCR_XSTOP;
+	if (cflag & PARENB) {
+		fcr |= PSIONW_UARTFCR_PRTEN;
+		if (!(cflag & PARODD))
+			fcr |= PSIONW_UARTFCR_EVENPRT;
+	}
+	if (port->fifosize > 1)
+		fcr |= PSIONW_UARTFCR_UFIFOEN;
+
+	port->read_status_mask = PSIONW_UARTRSR_OE;
+	if (iflag & INPCK)
+		port->read_status_mask |= PSIONW_UARTRSR_FE | PSIONW_UARTRSR_PE;
+
+	/*
+	 * Characters to ignore
+	 */
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |=
+		    PSIONW_UARTRSR_FE | PSIONW_UARTRSR_PE;
+	if (iflag & IGNBRK) {
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= PSIONW_UARTRSR_OE;
+	}
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+//	if ((cflag & CREAD) == 0)
+//		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+
+	/* first, disable everything */
+	save_flags(flags);
+	cli();
+
+	/* Set baud rate */
+	quot -= 1;
+	UART_PUT_LCR(port, quot);
+
+	/* Set the frame control */
+	UART_PUT_FCR(port, fcr);
+
+	restore_flags(flags);
+}
+
+/*
+ * Release the memory region(s) being used by 'port'
+ */
+static void
+psionwuart_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
+psionwuart_request_port(struct uart_port *port)
+{
+	return request_region(port->mapbase, UART_PORT_SIZE, "serial_psionw")
+	    != NULL ? 0 : -EBUSY;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void
+psionwuart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_PSIONW;
+		psionwuart_request_port(port);
+	}
+}
+
+/*
+ * verify the new serial_struct (for TIOCSSERIAL).
+ */
+static int
+psionwuart_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_PSIONW)
+		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 psionw_pops = {
+	tx_empty:	psionwuart_tx_empty,
+	set_mctrl:	psionwuart_set_mctrl,
+	get_mctrl:	psionwuart_get_mctrl,
+	stop_tx:	psionwuart_stop_tx,
+	start_tx:	psionwuart_start_tx,
+	stop_rx:	psionwuart_stop_rx,
+	enable_ms:	psionwuart_enable_ms,
+	break_ctl:	psionwuart_break_ctl,
+	startup:	psionwuart_startup,
+	shutdown:	psionwuart_shutdown,
+	change_speed:	psionwuart_change_speed,
+	release_port:	psionwuart_release_port,
+	request_port:	psionwuart_request_port,
+	config_port:	psionwuart_config_port,
+	verify_port:	psionwuart_verify_port,
+};
+
+static struct uart_port psionw_ports[UART_NR] = {
+	{
+	      membase:	(void *) PSIONW_UART0_V_BASE,
+	      mapbase:	PSIONW_UART0_V_BASE,
+	      iotype:	SERIAL_IO_MEM,
+	      irq:	IRQ_UART1,
+	      uartclk:	7372800,
+	      fifosize:	16,
+	      ops:	&psionw_pops,
+	      flags:	ASYNC_BOOT_AUTOCONF,
+	 },
+	{
+	      membase:	(void *) PSIONW_UART1_V_BASE,
+	      mapbase:	PSIONW_UART1_V_BASE,
+	      iotype:	SERIAL_IO_MEM,
+	      irq:	IRQ_UART2,
+	      uartclk:	7372800,
+	      fifosize:	16,
+	      ops:	&psionw_pops,
+	      flags:	ASYNC_BOOT_AUTOCONF,
+	 }
+};
+
+#ifdef CONFIG_SERIAL_PSIONW_CONSOLE
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ *
+ *	Note that this is called with interrupts already disabled
+ */
+static void
+psionwuart_console_write(struct console *co, const char *s, u_int count)
+{
+	struct uart_port *port = psionw_ports + co->index;
+	unsigned int status, old_cr;
+	int i;
+
+	/*
+	 *	Ensure that the port is enabled.
+	 */
+	old_cr = UART_GET_CR(port);
+	UART_PUT_CR(port, PSIONW_UARTCR_UARTEN);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++) {
+		do {
+			status = UART_GET_FR(port);
+		} while (status & AMBA_UARTFR_TXFF);
+		UART_PUT_CHAR(port, s[i]);
+		if (s[i] == '\n') {
+			do {
+				status = UART_GET_FR(port);
+			} while (status & AMBA_UARTFR_TXFF);
+			UART_PUT_CHAR(port, '\r');
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the uart state.
+	 */
+	do {
+		status = UART_GET_FR(port);
+	} while (status & AMBA_UARTFR_BUSY);
+
+	UART_PUT_CR(port, old_cr);
+}
+
+static kdev_t
+psionwuart_console_device(struct console *co)
+{
+	return MKDEV(SERIAL_PSIONW_MAJOR, SERIAL_PSIONW_MINOR + co->index);
+}
+
+static void __init
+psionwuart_console_get_options(struct uart_port *port, int *baud, int *parity,
+			       int *bits)
+{
+	if (UART_GET_CR(port) & PSIONW_UARTCR_UARTEN) {
+		u_int ubrfcr, quot;
+
+		ubrfcr = UART_GET_FCR(port);
+
+		*parity = 'n';
+		if (ubrfcr & PSIONW_UARTFCR_PRTEN) {
+			if (ubrfcr & PSIONW_UARTFCR_EVENPRT)
+				*parity = 'e';
+			else
+				*parity = 'o';
+		}
+
+		if ((ubrfcr & PSIONW_UARTFCR_WRDLEN_MASK) == PSIONW_UARTFCR_WLEN_7)
+			*bits = 7;
+		else
+			*bits = 8;
+		quot = UART_GET_LCR(port) & PSIONW_UART_BAUD_MASK;
+
+		*baud = port->uartclk / (16 * (quot + 1));
+	}
+}
+
+static int __init
+psionwuart_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 38400;
+	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(psionw_ports, UART_NR, co);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		psionwuart_console_get_options(port, &baud, &parity, &bits);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console psionw_console = {
+	name:	SERIAL_PSIONW_NAME,
+	write:	psionwuart_console_write,
+#ifdef used_and_not_const_char_pointer
+	read:	psionwuart_console_read,
+#endif
+	device:	psionwuart_console_device,
+	setup:	psionwuart_console_setup,
+	flags:	CON_PRINTBUFFER,
+	index:	-1,
+};
+
+void __init
+psionwuart_console_init(void)
+{
+	register_console(&psionw_console);
+}
+
+#define PSIONW_CONSOLE	&psionw_console
+#else				/* !CONFIG_SERIAL_PSIONW_CONSOLE  */
+#define PSIONW_CONSOLE	NULL
+#endif				/* !CONFIG_SERIAL_PSIONW_CONSOLE  */
+
+static struct uart_driver psionw_reg = {
+	owner:		THIS_MODULE,
+	normal_major:	SERIAL_PSIONW_MAJOR,
+#ifdef CONFIG_DEVFS_FS
+	normal_name:	SERIAL_PSIONW_NAME,
+	callout_name:	CALLOUT_PSIONW_NAME,
+#else
+	normal_name:	SERIAL_PSIONW_NAME,
+	callout_name:	CALLOUT_PSIONW_NAME,
+#endif
+
+	normal_driver:	&normal,
+	callout_major:	CALLOUT_PSIONW_MAJOR,
+	callout_driver:	&callout,
+
+	table:		psionw_table,
+	termios:	psionw_termios,
+	termios_locked:	psionw_termios_locked,
+
+	minor:		SERIAL_PSIONW_MINOR,
+	nr:		UART_NR,
+
+	port:		psionw_ports,
+	cons:		PSIONW_CONSOLE,
+};
+
+static int __init
+psionwuart_init(void)
+{
+	return uart_register_driver(&psionw_reg);
+}
+
+static void __exit
+psionwuart_exit(void)
+{
+	uart_unregister_driver(&psionw_reg);
+}
+
+module_init(psionwuart_init);
+module_exit(psionwuart_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR
+    ("Yuji Shinokawa <ysh@mob.or.jp> Tony Lindgren <tony@atomide.com>");
+MODULE_DESCRIPTION("Psion Windermere serial driver");
+MODULE_LICENSE("GPL");
