Skip to content

Commit e61c38d

Browse files
Uwe Kleine-Königgregkh
authored andcommitted
serial: imx: setup DCEDTE early and ensure DCD and RI irqs to be off
If the UART is operated in DTE mode and UCR3_DCD or UCR3_RI are 1 (which is the reset default) and the opposite side pulls the respective line to its active level the irq triggers after it is requested in .probe. These irqs were already disabled in .startup but this might be too late. Also setup of the UFCR_DCEDTE bit (currently done in .set_termios) is done very late which is critical as it also controls direction of some pins. So setup UFCR_DCEDTE earlier (in .probe) and also disable the broken irqs in DTE mode there before requesting irqs. Acked-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 87838ae commit e61c38d

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

drivers/tty/serial/imx.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,19 +1317,10 @@ static int imx_startup(struct uart_port *port)
13171317
if (!is_imx1_uart(sport)) {
13181318
temp = readl(sport->port.membase + UCR3);
13191319

1320-
/*
1321-
* The effect of RI and DCD differs depending on the UFCR_DCEDTE
1322-
* bit. In DCE mode they control the outputs, in DTE mode they
1323-
* enable the respective irqs. At least the DCD irq cannot be
1324-
* cleared on i.MX25 at least, so it's not usable and must be
1325-
* disabled. I don't have test hardware to check if RI has the
1326-
* same problem but I consider this likely so it's disabled for
1327-
* now, too.
1328-
*/
1329-
temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP |
1330-
UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
1320+
temp |= UCR3_DTRDEN | UCR3_RI | UCR3_DCD;
13311321

13321322
if (sport->dte_mode)
1323+
/* disable broken interrupts */
13331324
temp &= ~(UCR3_RI | UCR3_DCD);
13341325

13351326
writel(temp, sport->port.membase + UCR3);
@@ -1584,8 +1575,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
15841575

15851576
ufcr = readl(sport->port.membase + UFCR);
15861577
ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div);
1587-
if (sport->dte_mode)
1588-
ufcr |= UFCR_DCEDTE;
15891578
writel(ufcr, sport->port.membase + UFCR);
15901579

15911580
writel(num, sport->port.membase + UBIR);
@@ -2153,6 +2142,27 @@ static int serial_imx_probe(struct platform_device *pdev)
21532142
UCR1_TXMPTYEN | UCR1_RTSDEN);
21542143
writel_relaxed(reg, sport->port.membase + UCR1);
21552144

2145+
if (!is_imx1_uart(sport) && sport->dte_mode) {
2146+
/*
2147+
* The DCEDTE bit changes the direction of DSR, DCD, DTR and RI
2148+
* and influences if UCR3_RI and UCR3_DCD changes the level of RI
2149+
* and DCD (when they are outputs) or enables the respective
2150+
* irqs. So set this bit early, i.e. before requesting irqs.
2151+
*/
2152+
writel(UFCR_DCEDTE, sport->port.membase + UFCR);
2153+
2154+
/*
2155+
* Disable UCR3_RI and UCR3_DCD irqs. They are also not
2156+
* enabled later because they cannot be cleared
2157+
* (confirmed on i.MX25) which makes them unusable.
2158+
*/
2159+
writel(IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP | UCR3_DSR,
2160+
sport->port.membase + UCR3);
2161+
2162+
} else {
2163+
writel(0, sport->port.membase + UFCR);
2164+
}
2165+
21562166
clk_disable_unprepare(sport->clk_ipg);
21572167

21582168
/*

0 commit comments

Comments
 (0)