Commit ceca629e authored by Sascha Hauer's avatar Sascha Hauer Committed by Russell King

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

Patch from Sascha Hauer

handle rts interrupt
Signed-off-by: default avatarGiancarlo Formicuccia <giancarlo.formicuccia@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 9f693d7b
...@@ -73,7 +73,7 @@ struct imx_port { ...@@ -73,7 +73,7 @@ struct imx_port {
struct uart_port port; struct uart_port port;
struct timer_list timer; struct timer_list timer;
unsigned int old_status; unsigned int old_status;
int txirq,rxirq; int txirq,rxirq,rtsirq;
}; };
/* /*
...@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port) ...@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port)
imx_transmit_buffer(sport); 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) static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct imx_port *sport = (struct imx_port *)dev_id; struct imx_port *sport = (struct imx_port *)dev_id;
...@@ -386,15 +402,21 @@ static int imx_startup(struct uart_port *port) ...@@ -386,15 +402,21 @@ static int imx_startup(struct uart_port *port)
if (retval) goto error_out1; if (retval) goto error_out1;
retval = request_irq(sport->txirq, imx_txint, 0, retval = request_irq(sport->txirq, imx_txint, 0,
"imx-uart", sport); DRIVER_NAME, sport);
if (retval) goto error_out2; 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 * Finally, clear and enable interrupts
*/ */
USR1((u32)sport->port.membase) = USR1_RTSD;
UCR1((u32)sport->port.membase) |= 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); UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
/* /*
...@@ -406,6 +428,8 @@ static int imx_startup(struct uart_port *port) ...@@ -406,6 +428,8 @@ static int imx_startup(struct uart_port *port)
return 0; return 0;
error_out3:
free_irq(sport->txirq, sport);
error_out2: error_out2:
free_irq(sport->rxirq, sport); free_irq(sport->rxirq, sport);
error_out1: error_out1:
...@@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port) ...@@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)
/* /*
* Free the interrupts * Free the interrupts
*/ */
free_irq(sport->rtsirq, sport);
free_irq(sport->txirq, sport); free_irq(sport->txirq, sport);
free_irq(sport->rxirq, sport); free_irq(sport->rxirq, sport);
...@@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port) ...@@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)
*/ */
UCR1((u32)sport->port.membase) &= UCR1((u32)sport->port.membase) &=
~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
} }
static void static void
...@@ -522,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios, ...@@ -522,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
* disable interrupts and drain transmitter * disable interrupts and drain transmitter
*/ */
old_ucr1 = UCR1((u32)sport->port.membase); 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)) while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
barrier(); barrier();
...@@ -643,6 +668,7 @@ static struct imx_port imx_ports[] = { ...@@ -643,6 +668,7 @@ static struct imx_port imx_ports[] = {
{ {
.txirq = UART1_MINT_TX, .txirq = UART1_MINT_TX,
.rxirq = UART1_MINT_RX, .rxirq = UART1_MINT_RX,
.rtsirq = UART1_MINT_RTS,
.port = { .port = {
.type = PORT_IMX, .type = PORT_IMX,
.iotype = SERIAL_IO_MEM, .iotype = SERIAL_IO_MEM,
...@@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = { ...@@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = {
}, { }, {
.txirq = UART2_MINT_TX, .txirq = UART2_MINT_TX,
.rxirq = UART2_MINT_RX, .rxirq = UART2_MINT_RX,
.rtsirq = UART2_MINT_RTS,
.port = { .port = {
.type = PORT_IMX, .type = PORT_IMX,
.iotype = SERIAL_IO_MEM, .iotype = SERIAL_IO_MEM,
...@@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count) ...@@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
UCR1((u32)sport->port.membase) = UCR1((u32)sport->port.membase) =
(old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) (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; UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment