lkml.org 
[lkml]   [2022]   [Jan]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.15 059/188] tty: serial: imx: disable UCR4_OREN in .stop_rx() instead of .shutdown()
    Date
    From: Fugang Duan <fugang.duan@nxp.com>

    [ 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: 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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/tty/serial/imx.c | 7 +++++--
    1 file changed, 5 insertions(+), 2 deletions(-)

    diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
    index 51a9f9423b1a6..7820049aba5af 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);
    --
    2.34.1
    \
     
     \ /
      Last update: 2022-01-18 03:44    [W:2.941 / U:0.100 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site