Index: linux-2.6.30/Documentation/serial/direct
===================================================================
--- /dev/null
+++ linux-2.6.30/Documentation/serial/direct
@@ -0,0 +1,164 @@
+                    The direct serial interface
+		    ---------------------------
+
+Sometimes something in the kernel needs to use a serial port.  Maybe a
+device driver talks over a UART to its device.  Maybe a kernel
+debugger needs to run over a UART.  Maybe there is some kernel-level
+protocol that runs over a serial port.
+
+These sorts of things should normally use the tty line discipline for
+this, like ppp does.  This has several advantages: the driver does not
+need to be modified to support polling, the configuration of the
+serial port can be done by a user process, it can run over a pty as
+well as a UART (good for testing) and it's just the right thing to do
+in general.
+
+However, something may need to run when the system is not completely
+operational.  A kernel debugger, for instance, has to run when the
+kernel won't schedule.  Maybe a device needs to be accessed before the
+system is completely up.  Maybe the device needs something done to it
+when a panic occurs.  The direct interface exists for these needs.
+
+
+Driver Concerns
+---------------
+
+The low-level serial driver must support the poll functions to be able
+to be used as a direct interface and must register itself as a polled
+device.  If you don't need polling, well, you should be using the line
+discipline.  Beyond that, there are no special concerns for the driver.
+
+
+Using The Direct API
+--------------------
+
+The serial direct API uses as much of the existing interface to a UART
+as possible.  It uses the uart_port structure as the main interface
+between the user and the driver.  The user provides a struct
+uart_direct to the serial core to transfer information from the driver
+to the user.
+
+The user must claim the port with uart_get_direct_port().  It should
+do the following after the port is allocated:
+  1) If port->info->xmit.buf is NULL, set port->info->xmit.buf to a
+     byte array of size UART_XMIT_SIZE and set port->info->flags.
+     UIF_BOOT_ALLOCATED, and call uart_circ_clear(&port->info->xmit)
+  2) Set port->info->direct to the uart_direct structure for the user.
+  3) Initialize port->info->tlet to a tasklet function that will be
+     called when there is transmit buffer space ready, and set
+     the UIF_TASKLET_SETUP flag in port->info->flags.
+  4) Set port->info->direct->direct_data to whatever you need to
+     find the port in the direct callbacks.
+  5) Set port->info->direct->handle_char to an input character handler
+     routine.  See below for details.
+  6) Set port->info->direct->push to a routine to process input
+     characters.
+  7) Set the other routines in the direct structure as needed.
+  8) Call port->startup() to enable operation on the port and
+     port->set_termios() to do any configuration required on the port.
+
+When the user is done with the port, they should:
+  1) kill the tasklet in port->info->tlet
+  2) port->info->flags &= ~UIF_TASKLET_SETUP (to prevent your
+     tasklet routine from being called when the normal serial code
+     takes over).
+  3) If the driver supplied, port->info->xmit.buf, undo the changes
+     that were done to set it up, NULL the buffer pointer and clear
+     UIF_BOOT_ALLOCATED from port->info->flags.
+  4) call port->shutdown()
+
+to disable the port, then call uart_put_direct_port() to free the
+port.
+
+The uart_direct_write() function should be use write data to the UART.
+Data comes from the handle_char and push funcions in the uart_direct.
+Note that if the write buffer fills up, you can use the tasklet to
+tell you when data has been freed up in the write buffer.
+
+
+Polling the Interface
+---------------------
+
+Polling works much like the normal interface, except that you must
+call the port->poll() routine periodically and tell it what you want
+to poll (read, write, and/or modem control).  Also, the tasklets will
+not work, so any changes to CTS, DCD, or a break should be set as
+variables and actually processed once the port->poll() call returns.
+For transmit, the circular buffer status should be polled, too.
+This might look like
+
+	struct circ_buf *circ = uart_get_circ_buf(port);
+	port->ops->poll(port, UART_POLL_FLAGS_TX | UART_POLL_FLAGS_RX
+			| UART_POLL_FLAGS_MCTRL);
+	if (dcd_set) {
+		dcd_set = 0;
+		dcd_changed(...);
+	}
+	if (cts_set) {
+		cts_set = 0;
+		cts_changed(...);
+	}
+	if (uart_circ_chars_free(circ) > 0)
+		tx_ready(...);
+
+Polling is generally done when the entire system is single-threaded
+(like at panic time or when a debugger has shut down everything else),
+so locking is not that critical.
+
+
+The Direct API
+--------------
+
+The uart_direct structure has the following functions:
+  handle_break(port)
+	Called when a break comes in on the port.
+
+  handle_dcd_change(port, value)
+	Called when the DCD line changes on the port.  The status is
+	true if DCD is asserted, false if not.
+
+  handle_cts_change(port, value)
+	Called when the CTS line changes on the port.  The status is
+	true if CTS is asserted, false if not.
+
+  handle_char(port, status, overrun, ch, flag)
+	Handle a new input character.  status is a set of bits that
+	report errors.  If the bit specific by overrun (status & overrun != 0)
+	then an overrun has occured.  ch is the character.  flag reports
+	various conditions, like TTY_BREAK, TTY_PARITY, or TTY_FRAME for
+	a break, parity error, or framing error.  It is TTY_NORMAL for
+	normal characters without error.
+
+	Note that you should only queue the data in the above routine,
+	you should *NOT* process them because the port lock is held for
+	the port.  For breaks, DCD changes, and CTS
+	changes you should start a taskelet (or set a variable if
+	polling).  For characters, you should process them in the push
+	routine.
+
+  push(port)
+	Called when receipt of characters is complete, the user should
+	process incoming characters here (or schedule them to be
+	processed).
+
+The following functions are provided for the user:
+
+  struct uart_port *uart_get_direct_port(name, line, force)
+	Attempt to find a port with the given name and line.  The name
+	is something like "ttyS", the line is the line number of the
+	port.  If "force" is true, this call doesn't do any locking
+	and it doesn't care if the port is already in use.  Otherwise,
+	if the port is in use the call fails.  NULL is returned on a
+	failure, otherwise the uart port is returned.
+
+  uart_put_direct_port(port, force)
+	Free a port claimed with uart_get_direct_port.  If you
+	specified force when claiming the port, you should specify
+	force when returning it.
+
+  int uart_direct_write(port, buf, count)
+	Write count bytes from buf to the port's circular buffer.
+	This returns the number of bytes actually written. If the
+	number of bytes is larger than the circular buffer free space,
+	this will only write the number of bytes it can and return
+	immediately.
Index: linux-2.6.30/Documentation/serial/driver
===================================================================
--- linux-2.6.30.orig/Documentation/serial/driver
+++ linux-2.6.30/Documentation/serial/driver
@@ -24,14 +24,43 @@ console support.
 Console Support
 ---------------
 
-The serial core provides a few helper functions.  This includes identifing
-the correct port structure (via uart_get_console) and decoding command line
-arguments (uart_parse_options).
-
-There is also a helper function (uart_write_console) which performs a
-character by character write, translating newlines to CRLF sequences.
-Driver writers are recommended to use this function rather than implementing
-their own version.
+If the driver provides the poll functions, the serial core will
+provide most of the console handling for it.  Beyond the poll
+routines, the driver must do the following:
+
+  * #define SUPPORT_SYSRQ before including serial_core.h if the
+    console is enabled and CONFIG_MAGIC_SYSRQ is defined.
+
+  * Add the following code (replacing xxx with your driver name):
+
+#ifdef CONFIG_SERIAL_xxx_CONSOLE
+static struct console xxx_console = {
+	.name		= "ttyS"
+};
+#define xxx_CONSOLE	&xxx_console
+#else
+#define xxx_CONSOLE	NULL
+#endif
+
+
+static struct uart_driver xxx_reg
+{
+	.....
+	.cons = xxx_CONSOLE
+}
+
+static int __init xxx_polled_init(void)
+{
+	... Set up the ports to work polled at this point in time.
+
+	uart_register_polled(&xxx_reg);
+
+	return 0;
+}
+console_initcall(xxx_polled_init);
+
+This is the preferred method, as it allows the driver to work polled
+and as a console.
 
 
 Locking
@@ -307,6 +336,52 @@ hardware.
 	Locking: none.
 	Interrupts: caller dependent.
 
+  poll_startup(port,&rstate)
+	Set up the port to do polling.  The driver should go into a
+	state where it can be polled with the poll() call.  It may store
+	state information in rstate (a long value); that will be passed
+	to the corresponding poll_shutdown call.   The caller
+        must call this before calling the poll routine and this is
+	called with the port lock held and interrupts off.  The caller
+	is not allowed to release the port lock or re-enable
+	interrupts until after poll_shutdown is called.
+	If polling is not implemented, this does not need to be supplied.
+
+  poll_shutdown(port,state)
+	The driver will no longer be polled.  The state information is
+	the same value return in the rstate value of poll_startup.
+	If polling is not implemented, this does not need to be supplied.
+
+  poll(port, flags)
+	Poll the device for data.  This should work much like an
+	interrupt routine, except it should only check the flags
+	passed in, not everything.  The flags are:
+		UART_POLL_FLAGS_RX - poll for received data
+		UART_POLL_FLAGS_TX - poll for transmitted data
+		UART_POLL_FLAGS_MCTRL - poll for modem control
+	The poll routine should do the "normal" thing for received
+	data and modem control.  For transmit data, it should only
+	transmit data from the circ buffer and not do any flow
+	control or whatnot.
+	If polling is not implemented, this does not need to be supplied.
+
+  in_flow_control(port)
+	This should return true if the port is in flow control (CTS
+	is not asserted) and false if not.  This is only called from
+	a poll context.
+	If polling is not implemented, this does not need to be supplied.
+
+  port_default(port,&baud,&parity,&bits,&flow)
+	Return defaults for the console serial port.  This is so firmware
+	console settings can be transferred to the serial driver and it
+	can use the same values as the firmware.  baud and bits are number
+	values.  parity is of of the following characters: 'n', 'o', 'e'.
+	flow should be 'r' to turn on cts/rts flow control, or a space
+	to do nothing.
+	If polling or serial console is not implemented, this does not
+	need to be supplied.  It function is optional, if not supplied the
+	console will default to 9600n81.
+
 Other functions
 ---------------
 
@@ -382,6 +457,20 @@ uart_add_one_port()
 
 uart_remove_one_port()
 
+uart_register_polled()
+	Register a driver to work as a polled driver and possibly
+	a console (if configured as such).
+
+	Locking: none
+	Interrupts: enabled
+
+uart_unregister_polled()
+	Remove a polled registration.  If the driver was a console,
+	the next console in line will be used.
+
+	Locking: none
+	Interrupts: enabled
+
 Other notes
 -----------
 
Index: linux-2.6.30/drivers/serial/8250.c
===================================================================
--- linux-2.6.30.orig/drivers/serial/8250.c
+++ linux-2.6.30/drivers/serial/8250.c
@@ -30,8 +30,6 @@
 #include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
 #include <linux/serial_reg.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
@@ -1375,7 +1373,6 @@ static void serial8250_enable_ms(struct 
 static void
 receive_chars(struct uart_8250_port *up, unsigned int *status)
 {
-	struct tty_struct *tty = up->port.info->port.tty;
 	unsigned char ch, lsr = *status;
 	int max_count = 256;
 	char flag;
@@ -1442,15 +1439,12 @@ receive_chars(struct uart_8250_port *up,
 ignore_char:
 		lsr = serial_inp(up, UART_LSR);
 	} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
-	spin_unlock(&up->port.lock);
-	tty_flip_buffer_push(tty);
-	spin_lock(&up->port.lock);
 	*status = lsr;
 }
 
 static void transmit_chars(struct uart_8250_port *up)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = uart_get_circ_buf(&up->port);
 	int count;
 
 	if (up->port.x_char) {
@@ -1471,7 +1465,7 @@ static void transmit_chars(struct uart_8
 	count = up->tx_loadsz;
 	do {
 		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
-		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		xmit->tail = uart_wrap_circ_buf(xmit->tail + 1);
 		up->port.icount.tx++;
 		if (uart_circ_empty(xmit))
 			break;
@@ -1523,8 +1517,12 @@ static void serial8250_handle_port(struc
 
 	DEBUG_INTR("status = %x...", status);
 
-	if (status & (UART_LSR_DR | UART_LSR_BI))
+	if (status & (UART_LSR_DR | UART_LSR_BI)) {
 		receive_chars(up, &status);
+		spin_unlock_irqrestore(&up->port.lock, flags);
+		uart_push(&up->port);
+		spin_lock_irqsave(&up->port.lock, flags);
+	}
 	check_modem_status(up);
 	if (status & UART_LSR_THRE)
 		transmit_chars(up);
@@ -1732,6 +1730,7 @@ static void serial8250_timeout(unsigned 
 static void serial8250_backup_timeout(unsigned long data)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)data;
+	struct circ_buf *xmit = uart_get_circ_buf(&up->port);
 	unsigned int iir, ier = 0, lsr;
 	unsigned long flags;
 
@@ -1757,7 +1756,7 @@ static void serial8250_backup_timeout(un
 	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 	spin_unlock_irqrestore(&up->port.lock, flags);
 	if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
-	    (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
+	    (!uart_circ_empty(xmit) || up->port.x_char) &&
 	    (lsr & UART_LSR_THRE)) {
 		iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
 		iir |= UART_IIR_THRI;
@@ -1843,8 +1842,6 @@ static void serial8250_break_ctl(struct 
 	spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
 /*
  *	Wait for transmitter & holding register to empty
  */
@@ -2605,6 +2602,74 @@ serial8250_type(struct uart_port *port)
 	return uart_config[type].name;
 }
 
+static void serial8250_poll(struct uart_port *port, unsigned int flags)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *)port;
+	unsigned int status;
+
+	status = serial_inp(up, UART_LSR);
+
+	if ((flags & UART_POLL_FLAGS_RX) && (status & UART_LSR_DR))
+		receive_chars(up, &status);
+	else
+		up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
+
+	if (flags & UART_POLL_FLAGS_MCTRL)
+		check_modem_status(up);
+
+	if ((flags & UART_POLL_FLAGS_TX) && (status & UART_LSR_THRE)) {
+		struct circ_buf *xmit = uart_get_circ_buf(&up->port);
+
+		if (!uart_circ_empty(xmit)) {
+			serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+			xmit->tail = uart_wrap_circ_buf(xmit->tail + 1);
+			up->port.icount.tx++;
+		}
+	}
+}
+
+static int serial8250_poll_startup(struct uart_port *port,
+				   unsigned long *pflags)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *) port;
+
+	*pflags = serial_in(up, UART_IER);
+
+	if (up->capabilities & UART_CAP_UUE)
+		serial_out(up, UART_IER, UART_IER_UUE);
+	else
+		serial_out(up, UART_IER, 0);
+
+	return 0;
+}
+
+static void serial8250_poll_shutdown(struct uart_port *port,
+				     unsigned long pflags)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *) port;
+
+	serial_out(up, UART_IER, pflags);
+
+	/*
+	 *	The receive handling will happen properly because the
+	 *	receive ready bit will still be set; it is not cleared
+	 *	on read.  However, modem control will not, we must
+	 *	call it if we have saved something in the saved flags
+	 *	while processing with interrupts off.
+	 */
+	if (up->msr_saved_flags)
+		check_modem_status(up);
+}
+
+int serial8250_in_flow_control(struct uart_port *port)
+{
+	struct uart_8250_port *up = (struct uart_8250_port *) port;
+	unsigned int msr = serial_in(up, UART_MSR);
+
+	up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
+	return !(msr & UART_MSR_CTS);
+}
+
 static struct uart_ops serial8250_pops = {
 	.tx_empty	= serial8250_tx_empty,
 	.set_mctrl	= serial8250_set_mctrl,
@@ -2618,6 +2683,10 @@ static struct uart_ops serial8250_pops =
 	.shutdown	= serial8250_shutdown,
 	.set_termios	= serial8250_set_termios,
 	.pm		= serial8250_pm,
+	.poll		= serial8250_poll,
+	.poll_startup	= serial8250_poll_startup,
+	.poll_shutdown	= serial8250_poll_shutdown,
+	.in_flow_control = serial8250_in_flow_control,
 	.type		= serial8250_type,
 	.release_port	= serial8250_release_port,
 	.request_port	= serial8250_request_port,
@@ -2630,6 +2699,7 @@ static struct uart_ops serial8250_pops =
 };
 
 static struct uart_8250_port serial8250_ports[UART_NR];
+static struct uart_port *serial8250_pollable_ports[UART_NR];
 
 static void __init serial8250_isa_init_ports(void)
 {
@@ -2697,99 +2767,6 @@ serial8250_register_ports(struct uart_dr
 }
 
 #ifdef CONFIG_SERIAL_8250_CONSOLE
-
-static void serial8250_console_putchar(struct uart_port *port, int ch)
-{
-	struct uart_8250_port *up = (struct uart_8250_port *)port;
-
-	wait_for_xmitr(up, UART_LSR_THRE);
-	serial_out(up, UART_TX, ch);
-}
-
-/*
- *	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.
- */
-static void
-serial8250_console_write(struct console *co, const char *s, unsigned int count)
-{
-	struct uart_8250_port *up = &serial8250_ports[co->index];
-	unsigned long flags;
-	unsigned int ier;
-	int locked = 1;
-
-	touch_nmi_watchdog();
-
-	local_irq_save(flags);
-	if (up->port.sysrq) {
-		/* serial8250_handle_port() already took the lock */
-		locked = 0;
-	} else if (oops_in_progress) {
-		locked = spin_trylock(&up->port.lock);
-	} else
-		spin_lock(&up->port.lock);
-
-	/*
-	 *	First save the IER then disable the interrupts
-	 */
-	ier = serial_in(up, UART_IER);
-
-	if (up->capabilities & UART_CAP_UUE)
-		serial_out(up, UART_IER, UART_IER_UUE);
-	else
-		serial_out(up, UART_IER, 0);
-
-	uart_console_write(&up->port, s, count, serial8250_console_putchar);
-
-	/*
-	 *	Finally, wait for transmitter to become empty
-	 *	and restore the IER
-	 */
-	wait_for_xmitr(up, BOTH_EMPTY);
-	serial_out(up, UART_IER, ier);
-
-	/*
-	 *	The receive handling will happen properly because the
-	 *	receive ready bit will still be set; it is not cleared
-	 *	on read.  However, modem control will not, we must
-	 *	call it if we have saved something in the saved flags
-	 *	while processing with interrupts off.
-	 */
-	if (up->msr_saved_flags)
-		check_modem_status(up);
-
-	if (locked)
-		spin_unlock(&up->port.lock);
-	local_irq_restore(flags);
-}
-
-static int __init serial8250_console_setup(struct console *co, char *options)
-{
-	struct uart_port *port;
-	int baud = 9600;
-	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.
-	 */
-	if (co->index >= nr_uarts)
-		co->index = 0;
-	port = &serial8250_ports[co->index].port;
-	if (!port->iobase && !port->membase)
-		return -ENODEV;
-
-	if (options)
-		uart_parse_options(options, &baud, &parity, &bits, &flow);
-
-	return uart_set_options(port, co, baud, parity, bits, flow);
-}
-
 static int serial8250_console_early_setup(void)
 {
 	return serial8250_find_port_for_earlycon();
@@ -2797,26 +2774,9 @@ static int serial8250_console_early_setu
 
 static struct console serial8250_console = {
 	.name		= "ttyS",
-	.write		= serial8250_console_write,
-	.device		= uart_console_device,
-	.setup		= serial8250_console_setup,
-	.early_setup	= serial8250_console_early_setup,
-	.flags		= CON_PRINTBUFFER,
-	.index		= -1,
-	.data		= &serial8250_reg,
+	.early_setup	= serial8250_console_early_setup
 };
 
-static int __init serial8250_console_init(void)
-{
-	if (nr_uarts > UART_NR)
-		nr_uarts = UART_NR;
-
-	serial8250_isa_init_ports();
-	register_console(&serial8250_console);
-	return 0;
-}
-console_initcall(serial8250_console_init);
-
 int serial8250_find_port(struct uart_port *p)
 {
 	int line;
@@ -2844,6 +2804,33 @@ static struct uart_driver serial8250_reg
 	.cons			= SERIAL8250_CONSOLE,
 };
 
+static int __init serial8250_polled_init(void)
+{
+	int i;
+	static int initialized;
+
+	if (initialized)
+		return 0;
+	initialized = 1;
+
+	if (nr_uarts > UART_NR)
+		nr_uarts = UART_NR;
+
+	serial8250_isa_init_ports();
+
+	for (i = 0; i < nr_uarts; i++) {
+		serial8250_ports[i].port.ops = &serial8250_pops;
+		serial8250_pollable_ports[i] = &serial8250_ports[i].port;
+	}
+	serial8250_reg.pollable_ports = serial8250_pollable_ports;
+	serial8250_reg.nr_pollable = nr_uarts;
+
+	uart_register_polled(&serial8250_reg);
+
+	return 0;
+}
+console_initcall(serial8250_polled_init);
+
 /*
  * early_serial_setup - early registration for 8250 ports
  *
@@ -3159,6 +3146,8 @@ static int __init serial8250_init(void)
 		"%d ports, IRQ sharing %sabled\n", nr_uarts,
 		share_irqs ? "en" : "dis");
 
+	serial8250_polled_init();
+
 #ifdef CONFIG_SPARC
 	ret = sunserial_register_minors(&serial8250_reg, UART_NR);
 #else
@@ -3194,6 +3183,8 @@ unreg_uart_drv:
 #else
 	uart_unregister_driver(&serial8250_reg);
 #endif
+
+	uart_unregister_polled(&serial8250_reg);
 out:
 	return ret;
 }
@@ -3217,6 +3208,8 @@ static void __exit serial8250_exit(void)
 #else
 	uart_unregister_driver(&serial8250_reg);
 #endif
+
+	uart_unregister_polled(&serial8250_reg);
 }
 
 module_init(serial8250_init);
Index: linux-2.6.30/drivers/serial/mpsc.c
===================================================================
--- linux-2.6.30.orig/drivers/serial/mpsc.c
+++ linux-2.6.30/drivers/serial/mpsc.c
@@ -57,8 +57,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/console.h>
@@ -936,7 +934,6 @@ static int serial_polled;
 static int mpsc_rx_intr(struct mpsc_port_info *pi)
 {
 	struct mpsc_rx_desc *rxre;
-	struct tty_struct *tty = pi->port.info->port.tty;
 	u32	cmdstat, bytes_in, i;
 	int	rc = 0;
 	u8	*bp;
@@ -966,17 +963,6 @@ static int mpsc_rx_intr(struct mpsc_port
 			return 0;
 		}
 #endif
-		/* Following use of tty struct directly is deprecated */
-		if (unlikely(tty_buffer_request_room(tty, bytes_in)
-					< bytes_in)) {
-			if (tty->low_latency)
-				tty_flip_buffer_push(tty);
-			/*
-			 * If this failed then we will throw away the bytes
-			 * but must do so to clear interrupts.
-			 */
-		}
-
 		bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
 		dma_cache_sync(pi->port.dev, (void *)bp, MPSC_RXBE_SIZE,
 				DMA_FROM_DEVICE);
@@ -1017,8 +1003,6 @@ static int mpsc_rx_intr(struct mpsc_port
 				flag = TTY_BREAK;
 			else if (cmdstat & SDMA_DESC_CMDSTAT_FR)
 				flag = TTY_FRAME;
-			else if (cmdstat & SDMA_DESC_CMDSTAT_OR)
-				flag = TTY_OVERRUN;
 			else if (cmdstat & SDMA_DESC_CMDSTAT_PE)
 				flag = TTY_PARITY;
 		}
@@ -1039,10 +1023,14 @@ static int mpsc_rx_intr(struct mpsc_port
 						| SDMA_DESC_CMDSTAT_FR
 						| SDMA_DESC_CMDSTAT_OR)))
 				&& !(cmdstat & pi->port.ignore_status_mask)) {
-			tty_insert_flip_char(tty, *bp, flag);
+			uart_insert_char(&pi->port, cmdstat,
+					 SDMA_DESC_CMDSTAT_OR,
+					 *bp, flag);
 		} else {
 			for (i=0; i<bytes_in; i++)
-				tty_insert_flip_char(tty, *bp++, TTY_NORMAL);
+				uart_insert_char(&pi->port, cmdstat,
+						 SDMA_DESC_CMDSTAT_OR,
+						 *bp++, flag);
 
 			pi->port.icount.rx += bytes_in;
 		}
@@ -1080,7 +1068,6 @@ next_frame:
 	if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
 		mpsc_start_rx(pi);
 
-	tty_flip_buffer_push(tty);
 	return rc;
 }
 
@@ -1222,8 +1209,12 @@ static irqreturn_t mpsc_sdma_intr(int ir
 
 	spin_lock_irqsave(&pi->port.lock, iflags);
 	mpsc_sdma_intr_ack(pi);
-	if (mpsc_rx_intr(pi))
+	if (mpsc_rx_intr(pi)) {
 		rc = IRQ_HANDLED;
+		spin_unlock(&pi->port.lock);
+		uart_push(&pi->port);
+		spin_lock(&pi->port.lock);
+	}
 	if (mpsc_tx_intr(pi))
 		rc = IRQ_HANDLED;
 	spin_unlock_irqrestore(&pi->port.lock, iflags);
@@ -1662,6 +1653,60 @@ static void mpsc_put_poll_char(struct ua
 }
 #endif
 
+static void mpsc_poll(struct uart_port *port, unsigned int flags)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	if (flags & UART_POLL_FLAGS_TX) {
+		mpsc_sdma_intr_ack(pi);
+		mpsc_tx_intr(pi);
+	}
+	if (flags & UART_POLL_FLAGS_RX)
+		mpsc_rx_intr(pi);
+}
+
+static int mpsc_poll_startup(struct uart_port *port, unsigned long *pflags)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	while (pi->txr_head != pi->txr_tail) {
+		while (mpsc_sdma_tx_active(pi))
+			udelay(100);
+		mpsc_sdma_intr_ack(pi);
+		mpsc_tx_intr(pi);
+	}
+
+	while (mpsc_sdma_tx_active(pi))
+		udelay(100);
+
+	return 0;
+}
+
+static void mpsc_poll_shutdown(struct uart_port *port, unsigned long pflags)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	mpsc_sdma_intr_ack(pi);
+}
+
+static int mpsc_in_flow_control(struct uart_port *port)
+{
+	return 0;
+}
+
+static int mpsc_port_defaults(struct uart_port *port, int *baud, int *parity,
+			      int *bits, int *flow)
+{
+	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+
+	*baud = pi->default_baud;
+	*bits = pi->default_bits;
+	*parity = pi->default_parity;
+	*flow = pi->default_flow;
+
+	return 0;
+}
+
 static struct uart_ops mpsc_pops = {
 	.tx_empty	= mpsc_tx_empty,
 	.set_mctrl	= mpsc_set_mctrl,
@@ -1674,6 +1719,11 @@ static struct uart_ops mpsc_pops = {
 	.startup	= mpsc_startup,
 	.shutdown	= mpsc_shutdown,
 	.set_termios	= mpsc_set_termios,
+	.poll		= mpsc_poll,
+	.poll_startup	= mpsc_poll_startup,
+	.poll_shutdown	= mpsc_poll_shutdown,
+	.in_flow_control = mpsc_in_flow_control,
+	.port_defaults	= mpsc_port_defaults,
 	.type		= mpsc_type,
 	.release_port	= mpsc_release_port,
 	.request_port	= mpsc_request_port,
@@ -1694,120 +1744,14 @@ static struct uart_ops mpsc_pops = {
  */
 
 #ifdef CONFIG_SERIAL_MPSC_CONSOLE
-static void mpsc_console_write(struct console *co, const char *s, uint count)
-{
-	struct mpsc_port_info *pi = &mpsc_ports[co->index];
-	u8 *bp, *dp, add_cr = 0;
-	int i;
-	unsigned long iflags;
-
-	spin_lock_irqsave(&pi->tx_lock, iflags);
-
-	while (pi->txr_head != pi->txr_tail) {
-		while (mpsc_sdma_tx_active(pi))
-			udelay(100);
-		mpsc_sdma_intr_ack(pi);
-		mpsc_tx_intr(pi);
-	}
-
-	while (mpsc_sdma_tx_active(pi))
-		udelay(100);
-
-	while (count > 0) {
-		bp = dp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
-
-		for (i = 0; i < MPSC_TXBE_SIZE; i++) {
-			if (count == 0)
-				break;
-
-			if (add_cr) {
-				*(dp++) = '\r';
-				add_cr = 0;
-			} else {
-				*(dp++) = *s;
-
-				if (*(s++) == '\n') { /* add '\r' after '\n' */
-					add_cr = 1;
-					count++;
-				}
-			}
-
-			count--;
-		}
-
-		dma_cache_sync(pi->port.dev, (void *)bp, MPSC_TXBE_SIZE,
-				DMA_BIDIRECTIONAL);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-		if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-			flush_dcache_range((ulong)bp,
-					(ulong)bp + MPSC_TXBE_SIZE);
-#endif
-		mpsc_setup_tx_desc(pi, i, 0);
-		pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
-		mpsc_sdma_start_tx(pi);
-
-		while (mpsc_sdma_tx_active(pi))
-			udelay(100);
-
-		pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1);
-	}
-
-	spin_unlock_irqrestore(&pi->tx_lock, iflags);
-}
-
-static int __init mpsc_console_setup(struct console *co, char *options)
-{
-	struct mpsc_port_info *pi;
-	int baud, bits, parity, flow;
-
-	pr_debug("mpsc_console_setup[%d]: options: %s\n", co->index, options);
-
-	if (co->index >= MPSC_NUM_CTLRS)
-		co->index = 0;
-
-	pi = &mpsc_ports[co->index];
-
-	baud = pi->default_baud;
-	bits = pi->default_bits;
-	parity = pi->default_parity;
-	flow = pi->default_flow;
-
-	if (!pi->port.ops)
-		return -ENODEV;
-
-	spin_lock_init(&pi->port.lock);	/* Temporary fix--copied from 8250.c */
-
-	if (options)
-		uart_parse_options(options, &baud, &parity, &bits, &flow);
-
-	return uart_set_options(&pi->port, co, baud, parity, bits, flow);
-}
-
 static struct console mpsc_console = {
 	.name	= MPSC_DEV_NAME,
-	.write	= mpsc_console_write,
-	.device	= uart_console_device,
-	.setup	= mpsc_console_setup,
-	.flags	= CON_PRINTBUFFER,
-	.index	= -1,
-	.data	= &mpsc_reg,
 };
-
-static int __init mpsc_late_console_init(void)
-{
-	pr_debug("mpsc_late_console_init: Enter\n");
-
-	if (!(mpsc_console.flags & CON_ENABLED))
-		register_console(&mpsc_console);
-	return 0;
-}
-
-late_initcall(mpsc_late_console_init);
-
 #define MPSC_CONSOLE	&mpsc_console
 #else
 #define MPSC_CONSOLE	NULL
 #endif
+
 /*
  ******************************************************************************
  *
@@ -1940,9 +1884,35 @@ static struct uart_driver mpsc_reg = {
 	.major		= MPSC_MAJOR,
 	.minor		= MPSC_MINOR_START,
 	.nr		= MPSC_NUM_CTLRS,
-	.cons		= MPSC_CONSOLE,
 };
 
+struct mpsc_port_info *pid;
+static struct uart_port *mpsc_pollable_ports[MPSC_NUM_CTLRS];
+
+static void mpsc_polled_init(void)
+{
+	int i;
+
+	pid = &mpsc_ports[0];
+	pr_debug("mpsc_polled_init: Enter\n");
+
+	for (i = 0; i < MPSC_NUM_CTLRS; i++) {
+		/* Temporary fix--copied from 8250.c */
+		spin_lock_init(&mpsc_ports[i].port.lock);
+
+		mpsc_ports[i].port.ops = &mpsc_pops;
+		mpsc_pollable_ports[i] = &mpsc_ports[i].port;
+	}
+	mpsc_reg.pollable_ports = mpsc_pollable_ports;
+	mpsc_reg.nr_pollable = MPSC_NUM_CTLRS;
+	/*
+	 * Wait until here to set cons, so the uart_add_one_port calls
+	 * won't do a console add before we are ready.
+	 */
+	mpsc_reg.cons = MPSC_CONSOLE;
+	uart_register_polled(&mpsc_reg);
+}
+
 static int mpsc_drv_map_regs(struct mpsc_port_info *pi,
 		struct platform_device *pd)
 {
@@ -2035,6 +2005,7 @@ static void mpsc_drv_get_platform_data(s
 	pi->port.membase = pi->mpsc_base;
 	pi->port.mapbase = (ulong)pi->mpsc_base;
 	pi->port.ops = &mpsc_pops;
+	pi->port.dev = &pd->dev;
 
 	pi->mirror_regs = pdata->mirror_regs;
 	pi->cache_mgmt = pdata->cache_mgmt;
@@ -2087,6 +2058,8 @@ static int mpsc_drv_probe(struct platfor
 		}
 	}
 
+	mpsc_polled_init();
+
 	return rc;
 }
 
@@ -2128,9 +2101,11 @@ static int __init mpsc_drv_init(void)
 			if ((rc = platform_driver_register(&mpsc_driver))) {
 				platform_driver_unregister(&mpsc_shared_driver);
 				uart_unregister_driver(&mpsc_reg);
+				uart_unregister_polled(&mpsc_reg);
 			}
 		} else {
 			uart_unregister_driver(&mpsc_reg);
+			uart_unregister_polled(&mpsc_reg);
 		}
 	}
 
@@ -2142,6 +2117,7 @@ static void __exit mpsc_drv_exit(void)
 	platform_driver_unregister(&mpsc_driver);
 	platform_driver_unregister(&mpsc_shared_driver);
 	uart_unregister_driver(&mpsc_reg);
+	uart_unregister_polled(&mpsc_reg);
 	memset(mpsc_ports, 0, sizeof(mpsc_ports));
 	memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
 }
Index: linux-2.6.30/drivers/serial/serial_core.c
===================================================================
--- linux-2.6.30.orig/drivers/serial/serial_core.c
+++ linux-2.6.30/drivers/serial/serial_core.c
@@ -55,6 +55,7 @@ static struct lock_class_key port_lock_k
 #define uart_users(state)	((state)->count + (state)->info.port.blocked_open)
 
 #ifdef CONFIG_SERIAL_CORE_CONSOLE
+#include <linux/nmi.h>
 #define uart_console(port)	((port)->cons && (port)->cons->index == (port)->line)
 #else
 #define uart_console(port)	(0)
@@ -77,7 +78,8 @@ void uart_write_wakeup(struct uart_port 
 	 * closed.  No cookie for you.
 	 */
 	BUG_ON(!info);
-	tasklet_schedule(&info->tlet);
+	if (info->flags & UIF_TASKLET_SETUP)
+		tasklet_schedule(&info->tlet);
 }
 
 static void uart_stop(struct tty_struct *tty)
@@ -256,12 +258,13 @@ static void uart_shutdown(struct uart_st
 	/*
 	 * kill off our tasklet
 	 */
-	tasklet_kill(&info->tlet);
+	if (info->flags & UIF_TASKLET_SETUP)
+		tasklet_kill(&info->tlet);
 
 	/*
 	 * Free the transmit buffer page.
 	 */
-	if (info->xmit.buf) {
+	if (info->xmit.buf && !(info->flags & UIF_BOOT_ALLOCATED)) {
 		free_page((unsigned long)info->xmit.buf);
 		info->xmit.buf = NULL;
 	}
@@ -462,18 +465,25 @@ uart_change_speed(struct uart_state *sta
 static inline int
 __uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
 {
+	if (uart_circ_chars_free(circ) != 0) {
+		circ->buf[circ->head] = c;
+		circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
+		return 1;
+	}
+	return 0;
+}
+
+static inline int
+_uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
+{
 	unsigned long flags;
-	int ret = 0;
+	int ret;
 
 	if (!circ->buf)
 		return 0;
 
 	spin_lock_irqsave(&port->lock, flags);
-	if (uart_circ_chars_free(circ) != 0) {
-		circ->buf[circ->head] = c;
-		circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
-		ret = 1;
-	}
+	ret = __uart_put_char(port, circ, c);
 	spin_unlock_irqrestore(&port->lock, flags);
 	return ret;
 }
@@ -482,7 +492,7 @@ static int uart_put_char(struct tty_stru
 {
 	struct uart_state *state = tty->driver_data;
 
-	return __uart_put_char(state->port, &state->info.xmit, ch);
+	return _uart_put_char(state->port, &state->info.xmit, ch);
 }
 
 static void uart_flush_chars(struct tty_struct *tty)
@@ -490,6 +500,27 @@ static void uart_flush_chars(struct tty_
 	uart_start(tty);
 }
 
+static int uart_circ_write(struct circ_buf *circ, const unsigned char *buf,
+			   int count)
+{
+	int c, ret = 0;
+
+	while (1) {
+		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
+		if (count < c)
+			c = count;
+		if (c <= 0)
+			break;
+		memcpy(circ->buf + circ->head, buf, c);
+		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
+		buf += c;
+		count -= c;
+		ret += c;
+	}
+
+	return ret;
+}
+
 static int
 uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
@@ -497,7 +528,7 @@ uart_write(struct tty_struct *tty, const
 	struct uart_port *port;
 	struct circ_buf *circ;
 	unsigned long flags;
-	int c, ret = 0;
+	int ret;
 
 	/*
 	 * This means you called this function _after_ the port was
@@ -515,18 +546,7 @@ uart_write(struct tty_struct *tty, const
 		return 0;
 
 	spin_lock_irqsave(&port->lock, flags);
-	while (1) {
-		c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
-		if (count < c)
-			c = count;
-		if (c <= 0)
-			break;
-		memcpy(circ->buf + circ->head, buf, c);
-		circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
-		buf += c;
-		count -= c;
-		ret += c;
-	}
+	ret = uart_circ_write(circ, buf, count);
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	uart_start(tty);
@@ -1338,6 +1358,9 @@ static void uart_close(struct tty_struct
 	 * Wake up anyone trying to open this port.
 	 */
 	state->info.flags &= ~UIF_NORMAL_ACTIVE;
+	spin_lock_irq(&state->port->lock);
+	port->flags &= ~UPF_INUSE_NORMAL;
+	spin_unlock_irq(&state->port->lock);
 	wake_up_interruptible(&state->info.port.open_wait);
 
  done:
@@ -1476,6 +1499,7 @@ uart_block_til_ready(struct file *filp, 
 	struct uart_info *info = &state->info;
 	struct uart_port *port = state->port;
 	unsigned int mctrl;
+	int ret = 0;
 
 	info->port.blocked_open++;
 	state->count--;
@@ -1535,6 +1559,22 @@ uart_block_til_ready(struct file *filp, 
 
 		if (signal_pending(current))
 			break;
+
+		/*
+		 * The UPF_INUSE_NORMAL flag may have been cleared
+		 * while we were waiting on the port.  Make sure the
+		 * that the port wasn't grabbed by a direct user and
+		 * that the UPF_INUSE_NORMAL flags is set if we are
+		 * trying to grab the port now.
+		 */
+		spin_lock_irq(&state->port->lock);
+		if (port->flags & UPF_INUSE_DIRECT) {
+			spin_unlock_irq(&state->port->lock);
+			ret = -EAGAIN;
+			break;
+		}
+		port->flags |= UPF_INUSE_NORMAL;
+		spin_unlock_irq(&state->port->lock);
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&info->port.open_wait, &wait);
@@ -1542,13 +1582,19 @@ uart_block_til_ready(struct file *filp, 
 	state->count++;
 	info->port.blocked_open--;
 
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-
-	if (!info->port.tty || tty_hung_up_p(filp))
-		return -EAGAIN;
+	if (!ret) {
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		else if (!info->port.tty || tty_hung_up_p(filp))
+			return -EAGAIN;
+		if (ret) {
+			spin_lock_irq(&state->port->lock);
+			port->flags &= ~UPF_INUSE_NORMAL;
+			spin_unlock_irq(&state->port->lock);
+		}
+	}
 
-	return 0;
+	return ret;
 }
 
 static struct uart_state *uart_get(struct uart_driver *drv, int line)
@@ -1567,6 +1613,16 @@ static struct uart_state *uart_get(struc
 		ret = -ENXIO;
 		goto err_unlock;
 	}
+
+	spin_lock_irq(&state->port->lock);
+	if (state->port->flags & UPF_INUSE_DIRECT) {
+		spin_unlock_irq(&state->port->lock);
+		ret = -EAGAIN;
+		goto err_unlock;
+	}
+	state->port->flags |= UPF_INUSE_NORMAL;
+	spin_unlock_irq(&state->port->lock);
+
 	return state;
 
  err_unlock:
@@ -1654,6 +1710,16 @@ static int uart_open(struct tty_struct *
 	 */
 	if (retval == 0)
 		retval = uart_block_til_ready(filp, state);
+
+	spin_lock_irq(&state->port->lock);
+	if (retval && (state->port->flags & UPF_INUSE_NORMAL))
+		/*
+		 * The block failed, make sure that the inuse flag is
+		 * cleared.
+		 */
+		state->port->flags &= ~UPF_INUSE_NORMAL;
+	spin_unlock_irq(&state->port->lock);
+
 	mutex_unlock(&state->mutex);
 
 	/*
@@ -1954,6 +2020,175 @@ uart_set_options(struct uart_port *port,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(uart_set_options);
+
+static void uartdrv_console_write(struct console *co, const char *s,
+				  unsigned count)
+{
+	struct uart_driver *drv = co->data;
+	struct uart_port *port = drv->pollable_ports[co->index];
+	unsigned long flags, pstate;
+	struct circ_buf *circ;
+	int rv;
+	int locked = 1;
+	int tmout;
+	int free;
+
+	touch_nmi_watchdog();
+
+	if (count == 0)
+		return;
+
+	if (port->sysrq || oops_in_progress)
+		locked = spin_trylock_irqsave(&port->lock, flags);
+	else
+		spin_lock_irqsave(&port->lock, flags);
+
+	circ = &port->info->xmit;
+
+	rv = port->ops->poll_startup(port, &pstate);
+	if (rv)
+		goto out_err;
+
+	tmout = 10000;
+	while (count > 0) {
+		port->ops->poll(port, UART_POLL_FLAGS_TX);
+
+		free = uart_circ_chars_free(circ);
+
+		if (free) {
+			if (*s == '\n') {
+				if (free < 2)
+					goto do_timer;
+				__uart_put_char(port, circ, '\r');
+				free--;
+			}
+			__uart_put_char(port, circ, *s);
+			tmout = 10000;
+			count--;
+			free--;
+			s++;
+			continue;
+		}
+
+do_timer:
+		if (--tmout > 0) {
+			udelay(1);
+			continue;
+		}
+
+		if (port->ops->in_flow_control &&
+					(port->flags & UPF_CONS_FLOW)) {
+			/* Wait up to 1s for flow control. */
+			tmout = 1000000;
+			while (port->ops->in_flow_control(port)) {
+				if (--tmout == 0)
+					break;
+				udelay(1);
+				touch_nmi_watchdog();
+			}
+		}
+
+		port->ops->poll(port, UART_POLL_FLAGS_TX);
+		if (uart_circ_chars_free(circ) == 0) {
+			/*
+			 * We have timed out this character,
+			 * just go on.
+			 */
+			s++;
+			count--;
+		}
+		tmout = 10000;
+	}
+
+	/*
+	 * All the characters are in the buffer, wait for transmit to
+	 * finish.
+	 */
+
+	tmout = 10000;
+	free = uart_circ_chars_free(circ);
+	while ((free > 0) || !port->ops->tx_empty(port)) {
+		port->ops->poll(port, UART_POLL_FLAGS_TX);
+
+		if (free != uart_circ_chars_free(circ)) {
+			tmout = 10000;
+			free = uart_circ_chars_free(circ);
+			continue;
+		}
+		if (--tmout == 0)
+			break;
+		udelay(1);
+	}
+
+	port->ops->poll_shutdown(port, pstate);
+
+ out_err:
+
+	if (locked)
+		spin_unlock_irqrestore(&port->lock, flags);
+
+	/*
+	 * If the port is running something else, we may have opened
+	 * up some transmit space for it while writing the console, so
+	 * tell it that it may be able to write now.
+	 *
+	 * Note that this won't work with a direct serial driver, but
+	 * you shouldn't be running a console on the same port as a
+	 * direct serial driver, anyway.
+	 */
+	if (port->info->flags & UIF_INITIALIZED)
+		uart_write_wakeup(port);
+}
+
+static char console_buffer[UART_XMIT_SIZE];
+static struct uart_info console_info;
+
+static int uartdrv_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	struct uart_info *info;
+	struct uart_driver *drv = co->data;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+	int rv;
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= drv->nr_pollable)
+		co->index = 0;
+	port = drv->pollable_ports[co->index];
+
+	if (!port || (!port->iobase && !port->membase))
+		return -ENODEV;
+
+	if (port->ops->port_defaults) {
+		rv = port->ops->port_defaults(port, &baud, &parity, &bits,
+					      &flow);
+		if (rv)
+			return rv;
+	}
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	rv = uart_set_options(port, co, baud, parity, bits, flow);
+	if (rv)
+		return rv;
+
+	info = &console_info;
+	port->info = info;
+	info->xmit.buf = console_buffer;
+	info->flags |= UIF_BOOT_ALLOCATED;
+	uart_circ_clear(&info->xmit);
+	init_waitqueue_head(&info->port.open_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	return 0;
+}
 #endif /* CONFIG_SERIAL_CORE_CONSOLE */
 
 static void uart_change_pm(struct uart_state *state, int pm_state)
@@ -2306,6 +2541,185 @@ static const struct tty_operations uart_
 #endif
 };
 
+/*
+ * Holds a list of poll-capable uart drivers, so that polled driver
+ * users can look them up.
+ */
+static LIST_HEAD(polled_list);
+static DEFINE_MUTEX(polled_list_lock);
+
+#define PORT_INUSE (UPF_INUSE_NORMAL | UPF_INUSE_DIRECT)
+
+/**
+ *	uart_get_direct_port - Directly get a port for use
+ *	@name: The name to search for
+ *	@line: The line number to reserve
+ *      @force: If true, get the port even if it is in use already.
+ *
+ *	Find and reserve (if found) a serial port.  This is so things
+ *	like device drivers and debuggers can directly reserve a
+ *	serial port.  The force options is the serial port can be
+ *	taken over even while in use.  If the force option is set, it
+ *	is assumed that the system is in a stopped state and nothing
+ *	else will be touching the port until the debugger returns it.
+ */
+struct uart_port *uart_get_direct_port(char *name, int line, int force)
+{
+	struct uart_driver *drv;
+	struct uart_port *port = NULL;
+	unsigned long flags = 0;
+
+	if (!force)
+		mutex_lock(&polled_list_lock);
+	list_for_each_entry(drv, &polled_list, polled_link) {
+		if (strcmp(drv->dev_name, name) == 0) {
+			if (line < drv->nr_pollable
+						&& drv->pollable_ports[line])
+				port = drv->pollable_ports[line];
+			else
+				break;
+			if (!try_module_get(drv->owner)) {
+				port = NULL;
+				break;
+			}
+			if (!force)
+				spin_lock_irqsave(&port->lock, flags);
+			if (!force && port->flags & PORT_INUSE) {
+				spin_unlock_irqrestore(&port->lock, flags);
+				module_put(drv->owner);
+				port = NULL;
+				break;
+			}
+			port->flags |= UPF_INUSE_DIRECT;
+			if (!force)
+				spin_unlock_irqrestore(&port->lock, flags);
+			break;
+		}
+	}
+	if (!force)
+		mutex_unlock(&polled_list_lock);
+
+	return port;
+}
+EXPORT_SYMBOL(uart_get_direct_port);
+
+/**
+ *	uart_put_direct_port - Release a port reserved for direct use.
+ *	@port: The port to release
+ *      @force: If true, free the port even if it is in use already.
+ *
+ *	Free a port that was previously returned by uart_get_direct_port.
+ *	If you specified force in the get, you should do so in the put.
+ */
+int uart_put_direct_port(struct uart_port *port, int force)
+{
+	struct uart_driver *drv;
+	unsigned long flags = 0;
+	int i;
+	int retval = -EINVAL;
+
+	if (!force)
+		mutex_lock(&polled_list_lock);
+	list_for_each_entry(drv, &polled_list, polled_link) {
+		for (i = 0; i < drv->nr_pollable; i++) {
+			if (drv->pollable_ports[i] == port) {
+				if (!force)
+					spin_lock_irqsave(&port->lock, flags);
+				port->flags &= ~UPF_INUSE_DIRECT;
+				if (!force)
+					spin_unlock_irqrestore(&port->lock,
+							       flags);
+				module_put(drv->owner);
+				retval = 0;
+				goto out_unlock;
+			}
+		}
+	}
+ out_unlock:
+	if (!force)
+		mutex_unlock(&polled_list_lock);
+
+	return retval;
+}
+EXPORT_SYMBOL(uart_put_direct_port);
+
+/**
+ *	uart_direct_write - Write data as a direct serial user
+ *	@port: The port to write on
+ *	@buf: The data to write
+ *	@count: The number of bytes to write.
+ *
+ *	Write bytes to a serial port that is reserved with the
+ *	uart_get_direct_port() function.  This is non-blocking and
+ *	will return the number of bytes actually written.
+ */
+int
+uart_direct_write(struct uart_port *port, const unsigned char *buf, int count,
+		  int lock)
+{
+	struct circ_buf *circ;
+	unsigned long flags = 0; /* Keep us warning-free. */
+	int ret;
+
+	circ = &port->info->xmit;
+	if (lock)
+		spin_lock_irqsave(&port->lock, flags);
+	ret = uart_circ_write(circ, buf, count);
+	if (ret > 0)
+		port->ops->start_tx(port);
+	if (lock)
+		spin_unlock_irqrestore(&port->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(uart_direct_write);
+
+/**
+ *	uart_register_polled - register a driver to be used as a polled device
+ *	@drv: low level driver structure
+ *
+ *	Register a uart driver with the polled driver interface.  This
+ *	means that things that need polled I/O can use the driver at this
+ *	point.
+ */
+void uart_register_polled(struct uart_driver *drv)
+{
+	mutex_lock(&polled_list_lock);
+	list_add_tail(&drv->polled_link, &polled_list);
+	mutex_unlock(&polled_list_lock);
+
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+	if (drv->nr_pollable && drv->cons &&
+					!(drv->cons->flags & CON_ENABLED)) {
+		/* We manage the consoles for this driver. */
+		drv->cons->write = uartdrv_console_write;
+		drv->cons->device = uart_console_device;
+		drv->cons->setup = uartdrv_console_setup;
+		drv->cons->flags = CON_PRINTBUFFER;
+		drv->cons->data = drv;
+		drv->cons->index = -1;
+		register_console(drv->cons);
+	}
+#endif
+}
+EXPORT_SYMBOL(uart_register_polled);
+
+/**
+ *	uart_unregister_polled - unregister a driver previously registered
+ *      as a polled device
+ *	@drv: low level driver structure
+ */
+void uart_unregister_polled(struct uart_driver *drv)
+{
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+	if (drv->nr_pollable && drv->cons)
+		unregister_console(drv->cons);
+#endif
+	mutex_lock(&polled_list_lock);
+	list_del(&drv->polled_link);
+	mutex_unlock(&polled_list_lock);
+}
+EXPORT_SYMBOL(uart_unregister_polled);
+
 /**
  *	uart_register_driver - register a driver with the uart core layer
  *	@drv: low level driver structure
@@ -2367,8 +2781,11 @@ int uart_register_driver(struct uart_dri
 
 		tty_port_init(&state->info.port);
 		init_waitqueue_head(&state->info.delta_msr_wait);
-		tasklet_init(&state->info.tlet, uart_tasklet_action,
-			     (unsigned long)state);
+		if (!(state->info.flags & UIF_TASKLET_SETUP)) {
+			tasklet_init(&state->info.tlet, uart_tasklet_action,
+				     (unsigned long)state);
+			state->info.flags |= UIF_TASKLET_SETUP;
+		}
 	}
 
 	retval = tty_register_driver(normal);
@@ -2439,6 +2856,15 @@ int uart_add_one_port(struct uart_driver
 	state->pm_state = -1;
 
 	port->cons = drv->cons;
+	if (port->info) {
+		/* A console, copy stuff that we need. */
+		unsigned long flags;
+
+		spin_lock_irqsave(&port->lock, flags);
+		state->info.xmit = port->info->xmit;
+		state->info.flags |= port->info->flags;
+		spin_unlock_irqrestore(&port->lock, flags);
+	}
 	port->info = &state->info;
 
 	/*
@@ -2529,7 +2955,7 @@ int uart_remove_one_port(struct uart_dri
 	/*
 	 * Kill the tasklet, and free resources.
 	 */
-	if (info)
+	if (info && (info->flags & UIF_TASKLET_SETUP))
 		tasklet_kill(&info->tlet);
 
 	state->port = NULL;
Index: linux-2.6.30/include/linux/serial_core.h
===================================================================
--- linux-2.6.30.orig/include/linux/serial_core.h
+++ linux-2.6.30/include/linux/serial_core.h
@@ -183,6 +183,10 @@ struct uart_info;
 struct serial_struct;
 struct device;
 
+#define UART_POLL_FLAGS_RX	(1 << 0)	/* Poll Receiver */
+#define UART_POLL_FLAGS_TX	(1 << 1)	/* Poll Transmitter */
+#define UART_POLL_FLAGS_MCTRL	(1 << 2)	/* Poll modem control */
+
 /*
  * This structure describes all the operations that can be
  * done on the physical hardware.
@@ -207,6 +211,47 @@ struct uart_ops {
 			      unsigned int oldstate);
 	int		(*set_wake)(struct uart_port *, unsigned int state);
 
+
+	/*
+	 * Note: Poll routines must be called with the port lock held and
+	 * interrupts off.
+	 */
+
+	/*
+	 * The startup and shutdown routines must be called before
+	 * poll is used and after done calling poll.  You cannot allow
+	 * the driver code to be run by interrupts (or anything else)
+	 * between this.  A state value is returned by the startup
+	 * routine in pstate, you must pass that to the shutdown
+	 * routine.
+	 */
+	int		(*poll_startup)(struct uart_port *,
+					unsigned long *pstate);
+	void		(*poll_shutdown)(struct uart_port *,
+					 unsigned long pstate);
+
+	/*
+	 * Check the serial chip for I/O.  Flags is used to specify
+	 * what to check, see UART_POLL_FLAGS_xxx above.
+	 */
+	void		(*poll)(struct uart_port *, unsigned int flags);
+
+	/*
+	 * Is the port in flow-control (CTS is not asserted).  It is
+	 * optional an may be NULL and is only called if UPF_CONS_FLOW
+	 * is set in port->flags.
+	 */
+	int             (*in_flow_control)(struct uart_port *);
+
+	/*
+	 * Return reasonable settings for the port; it is primarily
+	 * there so firmware can pass console settings for the
+	 * console.
+	 */
+	int		(*port_defaults)(struct uart_port *,
+					 int *baud, int *parity, int *bits,
+					 int *flow);
+
 	/*
 	 * Return a string describing the type of the port
 	 */
@@ -286,6 +331,11 @@ struct uart_port {
 
 	upf_t			flags;
 
+/*
+ * The port lock protects UPF_INUSE_DIRECT and UPF_INUSE_NORMAL.  One
+ * of those two bits must be set before any other bits can be changed
+ * in port->flags.
+ */
 #define UPF_FOURPORT		((__force upf_t) (1 << 1))
 #define UPF_SAK			((__force upf_t) (1 << 2))
 #define UPF_SPD_MASK		((__force upf_t) (0x1030))
@@ -303,6 +353,8 @@ struct uart_port {
 #define UPF_MAGIC_MULTIPLIER	((__force upf_t) (1 << 16))
 #define UPF_CONS_FLOW		((__force upf_t) (1 << 23))
 #define UPF_SHARE_IRQ		((__force upf_t) (1 << 24))
+#define UPF_INUSE_NORMAL	((__force uif_t) (1 << 25))
+#define UPF_INUSE_DIRECT	((__force uif_t) (1 << 26))
 /* The exact UART type is known and should not be probed.  */
 #define UPF_FIXED_TYPE		((__force upf_t) (1 << 27))
 #define UPF_BOOT_AUTOCONF	((__force upf_t) (1 << 28))
@@ -346,6 +398,8 @@ struct uart_info {
  *
  * FIXME: use the ASY_ definitions
  */
+#define UIF_TASKLET_SETUP	((__force uif_t) (1 << 23))
+#define UIF_BOOT_ALLOCATED	((__force uif_t) (1 << 24))
 #define UIF_CHECK_CD		((__force uif_t) (1 << 25))
 #define UIF_CTS_FLOW		((__force uif_t) (1 << 26))
 #define UIF_NORMAL_ACTIVE	((__force uif_t) (1 << 29))
@@ -354,6 +408,9 @@ struct uart_info {
 
 	struct tasklet_struct	tlet;
 	wait_queue_head_t	delta_msr_wait;
+
+	/* For the direct serial interface */
+	struct uart_direct	*direct;
 };
 
 /*
@@ -378,6 +435,35 @@ struct uart_state {
 
 #define UART_XMIT_SIZE	PAGE_SIZE
 
+/*
+ * Structure used by the direct uart driver.
+ */
+struct uart_direct {
+	/* Generic data for use by the layered driver. */
+	void *direct_data;
+
+	/*
+	 * Port status, called with the port lock held.
+	 */
+	void (*handle_break)(struct uart_port *port);
+	void (*handle_dcd_change)(struct uart_port *port, unsigned int status);
+	void (*handle_cts_change)(struct uart_port *port, unsigned int status);
+
+	/*
+	 * A receive character from the port.  Called with the port
+	 * lock held, buffer and use the "push" function to actually
+	 * handle the characters.
+	 */
+	void (*handle_char)(struct uart_port *port, unsigned int status,
+			    unsigned int overrun, unsigned int ch,
+			    unsigned int flag);
+
+	/*
+	 * Done receiving characters for now, called with the port
+	 * lock not held.
+	 */
+	void (*push)(struct uart_port *port);
+};
 
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS		256
@@ -395,11 +481,24 @@ struct uart_driver {
 	struct console		*cons;
 
 	/*
+	 * If nr_pollable is non-zero, then pollable_ports is an array of uart
+	 * ports that can be used for polling.  The serial_core code
+	 * will assume two things:
+	 *   1) The driver has poll capability in the uart_ops.
+	 *   2) The driver wants the serial_core to manage the console
+	 *      pointed to by "cons" above.  It uses the poll capability
+	 *      to do this.
+	 */
+	int			 nr_pollable;
+	struct uart_port	**pollable_ports;
+
+	/*
 	 * these are private; the low level driver should not
 	 * touch these; they should be initialised to NULL
 	 */
 	struct uart_state	*state;
 	struct tty_driver	*tty_driver;
+	struct list_head        polled_link;
 };
 
 void uart_write_wakeup(struct uart_port *port);
@@ -431,6 +530,8 @@ void uart_console_write(struct uart_port
 /*
  * Port/driver registration/removal
  */
+void uart_register_polled(struct uart_driver *uart);
+void uart_unregister_polled(struct uart_driver *uart);
 int uart_register_driver(struct uart_driver *uart);
 void uart_unregister_driver(struct uart_driver *uart);
 int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
@@ -438,6 +539,14 @@ int uart_remove_one_port(struct uart_dri
 int uart_match_port(struct uart_port *port1, struct uart_port *port2);
 
 /*
+ * Direct serial port access.
+ */
+struct uart_port *uart_get_direct_port(char *name, int line, int force);
+int uart_put_direct_port(struct uart_port *port, int force);
+int uart_direct_write(struct uart_port *port, const unsigned char *buf,
+		      int count, int lock);
+
+/*
  * Power Management
  */
 int uart_suspend_port(struct uart_driver *reg, struct uart_port *port);
@@ -445,6 +554,8 @@ int uart_resume_port(struct uart_driver 
 
 #define uart_circ_empty(circ)		((circ)->head == (circ)->tail)
 #define uart_circ_clear(circ)		((circ)->head = (circ)->tail = 0)
+#define uart_get_circ_buf(port)		(&(port)->info->xmit)
+#define uart_wrap_circ_buf(val)		((val) & (UART_XMIT_SIZE - 1))
 
 #define uart_circ_chars_pending(circ)	\
 	(CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
@@ -455,6 +566,8 @@ int uart_resume_port(struct uart_driver 
 static inline int uart_tx_stopped(struct uart_port *port)
 {
 	struct tty_struct *tty = port->info->port.tty;
+	if (!tty)
+		return 0;
 	if(tty->stopped || tty->hw_stopped)
 		return 1;
 	return 0;
@@ -488,6 +601,13 @@ uart_handle_sysrq_char(struct uart_port 
 static inline int uart_handle_break(struct uart_port *port)
 {
 	struct uart_info *info = port->info;
+
+	if (info->direct) {
+		if (info->direct->handle_break)
+			info->direct->handle_break(port);
+		return 0;
+	}
+
 #ifdef SUPPORT_SYSRQ
 	if (port->cons && port->cons->index == port->line) {
 		if (!port->sysrq) {
@@ -510,7 +630,13 @@ static inline int uart_handle_break(stru
 static inline void
 uart_handle_dcd_change(struct uart_port *port, unsigned int status)
 {
-	struct uart_info *info = port->info;
+	struct uart_info *info = port->info;;
+
+	if (info->direct) {
+		if (info->direct->handle_dcd_change)
+			info->direct->handle_dcd_change(port, status);
+		return;
+	}
 
 	port->icount.dcd++;
 
@@ -536,7 +662,15 @@ static inline void
 uart_handle_cts_change(struct uart_port *port, unsigned int status)
 {
 	struct uart_info *info = port->info;
-	struct tty_struct *tty = info->port.tty;
+	struct tty_struct *tty;
+
+	if (info->direct) {
+		if (info->direct->handle_cts_change)
+			info->direct->handle_cts_change(port, status);
+		return;
+	}
+
+	tty = info->port.tty;
 
 	port->icount.cts++;
 
@@ -562,7 +696,19 @@ static inline void
 uart_insert_char(struct uart_port *port, unsigned int status,
 		 unsigned int overrun, unsigned int ch, unsigned int flag)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct uart_info *info = port->info;
+	struct tty_struct *tty;
+
+	if (info->direct) {
+		if (info->direct->handle_char)
+			info->direct->handle_char(port, status, overrun,
+						  ch, flag);
+		return;
+	}
+
+	tty = info->port.tty;
+	if (!tty)
+		return;
 
 	if ((status & port->ignore_status_mask & ~overrun) == 0)
 		tty_insert_flip_char(tty, ch, flag);
@@ -575,6 +721,23 @@ uart_insert_char(struct uart_port *port,
 		tty_insert_flip_char(tty, 0, TTY_OVERRUN);
 }
 
+static inline void
+uart_push(struct uart_port *port)
+{
+	struct uart_info *info = port->info;
+
+	if (info->direct) {
+		if (info->direct->push)
+			info->direct->push(port);
+		return;
+	}
+
+	if (!info->port.tty)
+		return;
+
+	tty_flip_buffer_push(info->port.tty);
+}
+
 /*
  *	UART_ENABLE_MS - determine if port should enable modem status irqs
  */
