summary refs log tree commit diff
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2016-03-24 14:24:22 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-30 09:26:55 -0700
commit16804d68bfaa7f5f5a73ab4a016ffeba33e87770 (patch)
tree55a9590a27ce8a78991b18592784fd4259c13806
parent4d845a62b3f5672a813777b8dbebca0bad456bac (diff)
downloadlinux-16804d68bfaa7f5f5a73ab4a016ffeba33e87770.tar.gz
serial: imx: make sure unhandled irqs are disabled
Make sure that events that are not handled in the irq function don't
trigger an interrupt.

When the serial port is operated in DTE mode, the events for DCD and RI
events are enabled after a system reset by default.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/imx.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 46769168fab7..aa07301df262 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1224,11 +1224,32 @@ static int imx_startup(struct uart_port *port)
 	temp |= (UCR2_RXEN | UCR2_TXEN);
 	if (!sport->have_rtscts)
 		temp |= UCR2_IRTS;
+	/*
+	 * make sure the edge sensitive RTS-irq is disabled,
+	 * we're using RTSD instead.
+	 */
+	if (!is_imx1_uart(sport))
+		temp &= ~UCR2_RTSEN;
 	writel(temp, sport->port.membase + UCR2);
 
 	if (!is_imx1_uart(sport)) {
 		temp = readl(sport->port.membase + UCR3);
-		temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
+
+		/*
+		 * The effect of RI and DCD differs depending on the UFCR_DCEDTE
+		 * bit. In DCE mode they control the outputs, in DTE mode they
+		 * enable the respective irqs. At least the DCD irq cannot be
+		 * cleared on i.MX25 at least, so it's not usable and must be
+		 * disabled. I don't have test hardware to check if RI has the
+		 * same problem but I consider this likely so it's disabled for
+		 * now, too.
+		 */
+		temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP |
+			UCR3_RI | UCR3_DCD;
+
+		if (sport->dte_mode)
+			temp &= ~(UCR3_RI | UCR3_DCD);
+
 		writel(temp, sport->port.membase + UCR3);
 	}