diff options
Diffstat (limited to 'drivers/serial/imx.c')
| -rw-r--r-- | drivers/serial/imx.c | 39 | 
1 files changed, 33 insertions, 6 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 53e0323d4b83..bdb4e454b8b0 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -73,7 +73,7 @@ struct imx_port {  	struct uart_port	port;  	struct timer_list	timer;  	unsigned int		old_status; -	int txirq,rxirq; +	int txirq,rxirq,rtsirq;  };  /* @@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port)  		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 @@ static int imx_startup(struct uart_port *port)  	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 @@ static int imx_startup(struct uart_port *port)  	return 0; +error_out3: +	free_irq(sport->txirq, sport);  error_out2:  	free_irq(sport->rxirq, sport);  error_out1: @@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)  	/*  	 * Free the interrupts  	 */ +	free_irq(sport->rtsirq, sport);  	free_irq(sport->txirq, sport);  	free_irq(sport->rxirq, sport); @@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)  	 */  	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 @@ imx_set_termios(struct uart_port *port, struct termios *termios,  	 * 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 @@ static struct imx_port imx_ports[] = {  	{  	.txirq  = UART1_MINT_TX,  	.rxirq  = UART1_MINT_RX, +	.rtsirq = UART1_MINT_RTS,  	.port	= {  		.type		= PORT_IMX,  		.iotype		= SERIAL_IO_MEM, @@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = {  	}, {  	.txirq  = UART2_MINT_TX,  	.rxirq  = UART2_MINT_RX, +	.rtsirq = UART2_MINT_RTS,  	.port	= {  		.type		= PORT_IMX,  		.iotype		= SERIAL_IO_MEM, @@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)  	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;  	/*  | 
