[ARM] 2971/1: i.MX uart handle rts irq

Patch from Sascha Hauer

handle rts interrupt

Signed-off-by: Giancarlo Formicuccia <giancarlo.formicuccia@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 53e0323..bdb4e45 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -73,7 +73,7 @@
 	struct uart_port	port;
 	struct timer_list	timer;
 	unsigned int		old_status;
-	int txirq,rxirq;
+	int txirq,rxirq,rtsirq;
 };
 
 /*
@@ -181,6 +181,22 @@
 		imx_transmit_buffer(sport);
 }
 
+static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct imx_port *sport = (struct imx_port *)dev_id;
+	unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+
+	USR1((u32)sport->port.membase) = USR1_RTSD;
+	uart_handle_cts_change(&sport->port, !!val);
+	wake_up_interruptible(&sport->port.info->delta_msr_wait);
+
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct imx_port *sport = (struct imx_port *)dev_id;
@@ -386,15 +402,21 @@
 	if (retval) goto error_out1;
 
 	retval = request_irq(sport->txirq, imx_txint, 0,
-			     "imx-uart", sport);
+			     DRIVER_NAME, sport);
 	if (retval) goto error_out2;
 
+	retval = request_irq(sport->rtsirq, imx_rtsint, 0,
+			     DRIVER_NAME, sport);
+	if (retval) goto error_out3;
+	set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);
+
 	/*
 	 * Finally, clear and enable interrupts
 	 */
 
+	USR1((u32)sport->port.membase) = USR1_RTSD;
 	UCR1((u32)sport->port.membase) |=
-	                 (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+	                 (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
 
 	UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
 	/*
@@ -406,6 +428,8 @@
 
 	return 0;
 
+error_out3:
+	free_irq(sport->txirq, sport);
 error_out2:
 	free_irq(sport->rxirq, sport);
 error_out1:
@@ -424,6 +448,7 @@
 	/*
 	 * Free the interrupts
 	 */
+	free_irq(sport->rtsirq, sport);
 	free_irq(sport->txirq, sport);
 	free_irq(sport->rxirq, sport);
 
@@ -432,7 +457,7 @@
 	 */
 
 	UCR1((u32)sport->port.membase) &=
-	                 ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
+	                 ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
 }
 
 static void
@@ -522,7 +547,7 @@
 	 * disable interrupts and drain transmitter
 	 */
 	old_ucr1 = UCR1((u32)sport->port.membase);
-	UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+	UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
 
 	while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
 		barrier();
@@ -643,6 +668,7 @@
 	{
 	.txirq  = UART1_MINT_TX,
 	.rxirq  = UART1_MINT_RX,
+	.rtsirq = UART1_MINT_RTS,
 	.port	= {
 		.type		= PORT_IMX,
 		.iotype		= SERIAL_IO_MEM,
@@ -658,6 +684,7 @@
 	}, {
 	.txirq  = UART2_MINT_TX,
 	.rxirq  = UART2_MINT_RX,
+	.rtsirq = UART2_MINT_RTS,
 	.port	= {
 		.type		= PORT_IMX,
 		.iotype		= SERIAL_IO_MEM,
@@ -737,7 +764,7 @@
 
 	UCR1((u32)sport->port.membase) =
 	                   (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
-	                   & ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
+	                   & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
 	UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
 
 	/*