diff options
author | Sascha Hauer <sascha@saschahauer.de> | 2005-10-12 14:58:08 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-10-12 14:58:08 -0400 |
commit | ceca629e0b4858d6b8bff260dab2e947d31aca56 (patch) | |
tree | 56b9a6a6dbf1674c7111dfaa255f294c895dd4e2 | |
parent | 9f693d7b149a74bac301ee47136359294cffed25 (diff) |
[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>
-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 { | |||
73 | struct uart_port port; | 73 | struct uart_port port; |
74 | struct timer_list timer; | 74 | struct timer_list timer; |
75 | unsigned int old_status; | 75 | unsigned int old_status; |
76 | int txirq,rxirq; | 76 | int txirq,rxirq,rtsirq; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* | 79 | /* |
@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port) | |||
181 | imx_transmit_buffer(sport); | 181 | imx_transmit_buffer(sport); |
182 | } | 182 | } |
183 | 183 | ||
184 | static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs) | ||
185 | { | ||
186 | struct imx_port *sport = (struct imx_port *)dev_id; | ||
187 | unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS; | ||
188 | unsigned long flags; | ||
189 | |||
190 | spin_lock_irqsave(&sport->port.lock, flags); | ||
191 | |||
192 | USR1((u32)sport->port.membase) = USR1_RTSD; | ||
193 | uart_handle_cts_change(&sport->port, !!val); | ||
194 | wake_up_interruptible(&sport->port.info->delta_msr_wait); | ||
195 | |||
196 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
197 | return IRQ_HANDLED; | ||
198 | } | ||
199 | |||
184 | static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs) | 200 | static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs) |
185 | { | 201 | { |
186 | struct imx_port *sport = (struct imx_port *)dev_id; | 202 | struct imx_port *sport = (struct imx_port *)dev_id; |
@@ -386,15 +402,21 @@ static int imx_startup(struct uart_port *port) | |||
386 | if (retval) goto error_out1; | 402 | if (retval) goto error_out1; |
387 | 403 | ||
388 | retval = request_irq(sport->txirq, imx_txint, 0, | 404 | retval = request_irq(sport->txirq, imx_txint, 0, |
389 | "imx-uart", sport); | 405 | DRIVER_NAME, sport); |
390 | if (retval) goto error_out2; | 406 | if (retval) goto error_out2; |
391 | 407 | ||
408 | retval = request_irq(sport->rtsirq, imx_rtsint, 0, | ||
409 | DRIVER_NAME, sport); | ||
410 | if (retval) goto error_out3; | ||
411 | set_irq_type(sport->rtsirq, IRQT_BOTHEDGE); | ||
412 | |||
392 | /* | 413 | /* |
393 | * Finally, clear and enable interrupts | 414 | * Finally, clear and enable interrupts |
394 | */ | 415 | */ |
395 | 416 | ||
417 | USR1((u32)sport->port.membase) = USR1_RTSD; | ||
396 | UCR1((u32)sport->port.membase) |= | 418 | UCR1((u32)sport->port.membase) |= |
397 | (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); | 419 | (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); |
398 | 420 | ||
399 | UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN); | 421 | UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN); |
400 | /* | 422 | /* |
@@ -406,6 +428,8 @@ static int imx_startup(struct uart_port *port) | |||
406 | 428 | ||
407 | return 0; | 429 | return 0; |
408 | 430 | ||
431 | error_out3: | ||
432 | free_irq(sport->txirq, sport); | ||
409 | error_out2: | 433 | error_out2: |
410 | free_irq(sport->rxirq, sport); | 434 | free_irq(sport->rxirq, sport); |
411 | error_out1: | 435 | error_out1: |
@@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port) | |||
424 | /* | 448 | /* |
425 | * Free the interrupts | 449 | * Free the interrupts |
426 | */ | 450 | */ |
451 | free_irq(sport->rtsirq, sport); | ||
427 | free_irq(sport->txirq, sport); | 452 | free_irq(sport->txirq, sport); |
428 | free_irq(sport->rxirq, sport); | 453 | free_irq(sport->rxirq, sport); |
429 | 454 | ||
@@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port) | |||
432 | */ | 457 | */ |
433 | 458 | ||
434 | UCR1((u32)sport->port.membase) &= | 459 | UCR1((u32)sport->port.membase) &= |
435 | ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); | 460 | ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); |
436 | } | 461 | } |
437 | 462 | ||
438 | static void | 463 | static void |
@@ -522,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios, | |||
522 | * disable interrupts and drain transmitter | 547 | * disable interrupts and drain transmitter |
523 | */ | 548 | */ |
524 | old_ucr1 = UCR1((u32)sport->port.membase); | 549 | old_ucr1 = UCR1((u32)sport->port.membase); |
525 | UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN); | 550 | UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); |
526 | 551 | ||
527 | while ( !(USR2((u32)sport->port.membase) & USR2_TXDC)) | 552 | while ( !(USR2((u32)sport->port.membase) & USR2_TXDC)) |
528 | barrier(); | 553 | barrier(); |
@@ -643,6 +668,7 @@ static struct imx_port imx_ports[] = { | |||
643 | { | 668 | { |
644 | .txirq = UART1_MINT_TX, | 669 | .txirq = UART1_MINT_TX, |
645 | .rxirq = UART1_MINT_RX, | 670 | .rxirq = UART1_MINT_RX, |
671 | .rtsirq = UART1_MINT_RTS, | ||
646 | .port = { | 672 | .port = { |
647 | .type = PORT_IMX, | 673 | .type = PORT_IMX, |
648 | .iotype = SERIAL_IO_MEM, | 674 | .iotype = SERIAL_IO_MEM, |
@@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = { | |||
658 | }, { | 684 | }, { |
659 | .txirq = UART2_MINT_TX, | 685 | .txirq = UART2_MINT_TX, |
660 | .rxirq = UART2_MINT_RX, | 686 | .rxirq = UART2_MINT_RX, |
687 | .rtsirq = UART2_MINT_RTS, | ||
661 | .port = { | 688 | .port = { |
662 | .type = PORT_IMX, | 689 | .type = PORT_IMX, |
663 | .iotype = SERIAL_IO_MEM, | 690 | .iotype = SERIAL_IO_MEM, |
@@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
737 | 764 | ||
738 | UCR1((u32)sport->port.membase) = | 765 | UCR1((u32)sport->port.membase) = |
739 | (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) | 766 | (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) |
740 | & ~(UCR1_TXMPTYEN | UCR1_RRDYEN); | 767 | & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); |
741 | UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; | 768 | UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; |
742 | 769 | ||
743 | /* | 770 | /* |