Skip to content
Snippets Groups Projects
Commit c6d9c77a authored by Fugang Duan's avatar Fugang Duan Committed by Greg Kroah-Hartman
Browse files

tty: serial: imx: disable UCR4_OREN in .stop_rx() instead of .shutdown()


[ Upstream commit 028e083832b06fdeeb290e1e57dc1f6702c4c215 ]

The UCR4_OREN should be disabled before disabling the uart receiver in
.stop_rx() instead of in the .shutdown().

Otherwise, if we have the overrun error during the receiver disable
process, the overrun interrupt will keep trigging until we disable the
OREN interrupt in the .shutdown(), because the ORE status can only be
cleared when read the rx FIFO or reset the controller.  Although the
called time between the receiver disable and OREN disable in .shutdown()
is very short, there is still the risk of endless interrupt during this
short period of time. So here change to disable OREN before the receiver
been disabled in .stop_rx().

Signed-off-by: default avatarFugang Duan <fugang.duan@nxp.com>
Signed-off-by: default avatarSherry Sun <sherry.sun@nxp.com>
Link: https://lore.kernel.org/r/20211125020349.4980-1-sherry.sun@nxp.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 93306292
No related branches found
No related tags found
No related merge requests found
...@@ -486,18 +486,21 @@ static void imx_uart_stop_tx(struct uart_port *port) ...@@ -486,18 +486,21 @@ static void imx_uart_stop_tx(struct uart_port *port)
static void imx_uart_stop_rx(struct uart_port *port) static void imx_uart_stop_rx(struct uart_port *port)
{ {
struct imx_port *sport = (struct imx_port *)port; struct imx_port *sport = (struct imx_port *)port;
u32 ucr1, ucr2; u32 ucr1, ucr2, ucr4;
ucr1 = imx_uart_readl(sport, UCR1); ucr1 = imx_uart_readl(sport, UCR1);
ucr2 = imx_uart_readl(sport, UCR2); ucr2 = imx_uart_readl(sport, UCR2);
ucr4 = imx_uart_readl(sport, UCR4);
if (sport->dma_is_enabled) { if (sport->dma_is_enabled) {
ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN); ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN);
} else { } else {
ucr1 &= ~UCR1_RRDYEN; ucr1 &= ~UCR1_RRDYEN;
ucr2 &= ~UCR2_ATEN; ucr2 &= ~UCR2_ATEN;
ucr4 &= ~UCR4_OREN;
} }
imx_uart_writel(sport, ucr1, UCR1); imx_uart_writel(sport, ucr1, UCR1);
imx_uart_writel(sport, ucr4, UCR4);
ucr2 &= ~UCR2_RXEN; ucr2 &= ~UCR2_RXEN;
imx_uart_writel(sport, ucr2, UCR2); imx_uart_writel(sport, ucr2, UCR2);
...@@ -1544,7 +1547,7 @@ static void imx_uart_shutdown(struct uart_port *port) ...@@ -1544,7 +1547,7 @@ static void imx_uart_shutdown(struct uart_port *port)
imx_uart_writel(sport, ucr1, UCR1); imx_uart_writel(sport, ucr1, UCR1);
ucr4 = imx_uart_readl(sport, UCR4); ucr4 = imx_uart_readl(sport, UCR4);
ucr4 &= ~(UCR4_OREN | UCR4_TCEN); ucr4 &= ~UCR4_TCEN;
imx_uart_writel(sport, ucr4, UCR4); imx_uart_writel(sport, ucr4, UCR4);
spin_unlock_irqrestore(&sport->port.lock, flags); spin_unlock_irqrestore(&sport->port.lock, flags);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment