diff --git a/drivers/serial/omap-serial.c b/drivers/serial/omap-serial.c
index 2a13a89..b20a825 100644
--- a/drivers/serial/omap-serial.c
+++ b/drivers/serial/omap-serial.c
@@ -111,6 +111,7 @@ struct uart_omap_port {
 	unsigned char		efr;
 	int			use_dma;
 	int			is_buf_dma_alloced;
+        int                     restore_autorts;
 	/*
 	 * Some bits in registers are cleared on a read, so they must
 	 * be saved whenever the register is read but the bits will not
@@ -132,6 +133,7 @@ static struct wake_lock omap_serial_wakelock;
 static void uart_tx_dma_callback(int lch, u16 ch_status, void *data);
 static void serial_omap_rx_timeout(unsigned long uart_no);
 static void serial_omap_start_rxdma(struct uart_omap_port *up);
+static void serial_omap_set_autorts(struct uart_omap_port *p, int set);
 
 #ifdef DEBUG
 static void serial_omap_display_reg(struct uart_port *port);
@@ -432,6 +434,11 @@ static void serial_omap_start_tx(struct uart_port *port)
 		up->ier |= UART_IER_THRI;
 		serial_out(up, UART_IER, up->ier);
 	}
+
+	if (up->restore_autorts) {
+	  serial_omap_set_autorts(up, 1);
+	  up->restore_autorts = 0;
+	}
 }
 
 static unsigned int check_modem_status(struct uart_omap_port *up)
@@ -529,8 +536,15 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
 	unsigned char mcr = 0;
 
 	DPRINTK("serial_omap_set_mctrl+%d\n", up->pdev->id);
-	if (mctrl & TIOCM_RTS)
-		mcr |= UART_MCR_RTS;
+	if (mctrl & TIOCM_RTS) {
+	  /*
+	   * We need to be careful not to cause
+	   * RTS to assert when we have a pending
+	   * auto-rts restore.
+	   */
+	  if (!up->restore_autorts)
+	    mcr |= UART_MCR_RTS;
+	}
 	if (mctrl & TIOCM_DTR)
 		mcr |= UART_MCR_DTR;
 	if (mctrl & TIOCM_OUT1)
@@ -559,6 +573,52 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
 	spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
+
+static void serial_omap_set_autorts(struct uart_omap_port *p, int set)
+{
+  u8 lcr_val = 0, mcr_val = 0, efr_val = 0;
+  u8 lcr_backup = 0, mcr_backup = 0, efr_backup = 0;
+
+  lcr_val = serial_in(p, UART_LCR);
+  lcr_backup = lcr_val;
+  /* Enter Config mode B */
+  serial_out(p, UART_LCR, 0xbf);
+
+  efr_val = serial_in(p, UART_EFR);
+  efr_backup = efr_val;
+
+  /*
+   * Enhanced functions write enable.
+   * Enables writes to IER[7:4], FCR[5:4], MCR[7:5]
+   */
+  serial_out(p, UART_EFR, efr_val | 0x10);
+
+  mcr_val = serial_in(p, UART_MCR);
+  mcr_backup = mcr_val;
+  /* Enable access to TCR_REG and TLR_REG */
+  serial_out(p, UART_MCR, mcr_val | 0x40);
+
+  /* Set RX_FIFO_TRIG levels */
+  serial_out(p, 0x18, 0x0f);
+
+  efr_val = serial_in(p, UART_EFR);
+  if (set)
+    serial_out(p, UART_EFR, efr_val | (1 << 6));
+  else
+    serial_out(p, UART_EFR, efr_val & ~(1 << 6));
+
+
+  mcr_val = serial_in(p, UART_MCR);
+  /* Restore original state of TCR_TLR access */
+  serial_out(p, UART_MCR, (mcr_val & ~0x40) | (mcr_backup & 0x40));
+
+  /* Enhanced function write disable. */
+  serial_out(p, UART_EFR, serial_in(p, UART_EFR) & ~0x10);
+
+  /* Normal operation */
+  serial_out(p, UART_LCR, lcr_backup);
+}
+
 static int serial_omap_startup(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
@@ -667,8 +727,23 @@ static void serial_omap_shutdown(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
 	unsigned long flags;
+	u8 lcr, efr;
 
 	DPRINTK("serial_omap_shutdown+%d\n", up->pdev->id);
+     
+	/* 
+	 * If we're using auto-rts then disable it.
+	 */
+	lcr = serial_in(up, UART_LCR);
+	serial_out(up, UART_LCR, 0xbf);
+	efr = serial_in(up, UART_EFR);
+	serial_out(up, UART_LCR, lcr);
+
+	if (efr & UART_EFR_RTS) {
+	  serial_omap_set_autorts(up, 0);
+	  up->restore_autorts = 1;
+	}
+
 	/*
 	 * Disable interrupts from this port
 	 */
@@ -930,7 +1005,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	/* Hardware Flow Control Configuration */
 
 	if (termios->c_cflag & CRTSCTS) {
-		efr |= (UART_EFR_CTS | UART_EFR_RTS);
+	        efr |= (UART_EFR_CTS | (up->restore_autorts ? 0 : UART_EFR_RTS));
 		serial_out(up, UART_LCR, 0x80);
 
 		up->mcr = serial_in(up, UART_MCR);
