summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFugang Duan <fugang.duan@nxp.com>2021-11-25 10:03:49 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-25 18:38:21 +0100
commit028e083832b06fdeeb290e1e57dc1f6702c4c215 (patch)
tree9615db421a77e3c04ac276432149f3a3ac38ff5f
parentc67643b46c28fc8bb7d81c65bc7eef18c3fbe972 (diff)
tty: serial: imx: disable UCR4_OREN in .stop_rx() instead of .shutdown()
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: Fugang Duan <fugang.duan@nxp.com> Signed-off-by: Sherry Sun <sherry.sun@nxp.com> Link: https://lore.kernel.org/r/20211125020349.4980-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/imx.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index fb75e3e0d828..df8a0c8b8b29 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -486,18 +486,21 @@ static void imx_uart_stop_tx(struct uart_port *port)
static void imx_uart_stop_rx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
- u32 ucr1, ucr2;
+ u32 ucr1, ucr2, ucr4;
ucr1 = imx_uart_readl(sport, UCR1);
ucr2 = imx_uart_readl(sport, UCR2);
+ ucr4 = imx_uart_readl(sport, UCR4);
if (sport->dma_is_enabled) {
ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN);
} else {
ucr1 &= ~UCR1_RRDYEN;
ucr2 &= ~UCR2_ATEN;
+ ucr4 &= ~UCR4_OREN;
}
imx_uart_writel(sport, ucr1, UCR1);
+ imx_uart_writel(sport, ucr4, UCR4);
ucr2 &= ~UCR2_RXEN;
imx_uart_writel(sport, ucr2, UCR2);
@@ -1544,7 +1547,7 @@ static void imx_uart_shutdown(struct uart_port *port)
imx_uart_writel(sport, ucr1, UCR1);
ucr4 = imx_uart_readl(sport, UCR4);
- ucr4 &= ~(UCR4_OREN | UCR4_TCEN);
+ ucr4 &= ~UCR4_TCEN;
imx_uart_writel(sport, ucr4, UCR4);
spin_unlock_irqrestore(&sport->port.lock, flags);