serial: imx: Restore original RXTL for console to fix data loss
commit f23c52aafb1675ab1d1f46914556d8e29cbbf7b3 upstream. Commit7a637784d5("serial: imx: reduce RX interrupt frequency") introduced a regression on the i.MX6UL EVK board. The issue can be reproduced with the following steps: - Open vi on the board. - Paste a text file (~150 characters). - Save the file, then repeat the process. - Compare the sha256sum of the saved files. The checksums do not match due to missing characters or entire lines. Fix this by restoring the RXTL value to 1 when the UART is used as a console. This ensures timely RX interrupts and reliable data reception in console mode. With this change, pasted content is saved correctly, and checksums are always consistent. Cc: stable <stable@kernel.org> Fixes:7a637784d5("serial: imx: reduce RX interrupt frequency") Signed-off-by: Fabio Estevam <festevam@gmail.com> Reviewed-by: Stefan Wahren <wahrenst@gmx.net> Link: https://lore.kernel.org/r/20250619114617.2791939-1-festevam@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
2b8788496f
commit
765af23196
@@ -233,6 +233,7 @@ struct imx_port {
|
|||||||
enum imx_tx_state tx_state;
|
enum imx_tx_state tx_state;
|
||||||
struct hrtimer trigger_start_tx;
|
struct hrtimer trigger_start_tx;
|
||||||
struct hrtimer trigger_stop_tx;
|
struct hrtimer trigger_stop_tx;
|
||||||
|
unsigned int rxtl;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct imx_port_ucrs {
|
struct imx_port_ucrs {
|
||||||
@@ -1328,6 +1329,7 @@ static void imx_uart_clear_rx_errors(struct imx_port *sport)
|
|||||||
|
|
||||||
#define TXTL_DEFAULT 8
|
#define TXTL_DEFAULT 8
|
||||||
#define RXTL_DEFAULT 8 /* 8 characters or aging timer */
|
#define RXTL_DEFAULT 8 /* 8 characters or aging timer */
|
||||||
|
#define RXTL_CONSOLE_DEFAULT 1
|
||||||
#define TXTL_DMA 8 /* DMA burst setting */
|
#define TXTL_DMA 8 /* DMA burst setting */
|
||||||
#define RXTL_DMA 9 /* DMA burst setting */
|
#define RXTL_DMA 9 /* DMA burst setting */
|
||||||
|
|
||||||
@@ -1445,7 +1447,7 @@ static void imx_uart_disable_dma(struct imx_port *sport)
|
|||||||
ucr1 &= ~(UCR1_RXDMAEN | UCR1_TXDMAEN | UCR1_ATDMAEN);
|
ucr1 &= ~(UCR1_RXDMAEN | UCR1_TXDMAEN | UCR1_ATDMAEN);
|
||||||
imx_uart_writel(sport, ucr1, UCR1);
|
imx_uart_writel(sport, ucr1, UCR1);
|
||||||
|
|
||||||
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
|
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
|
||||||
|
|
||||||
sport->dma_is_enabled = 0;
|
sport->dma_is_enabled = 0;
|
||||||
}
|
}
|
||||||
@@ -1470,7 +1472,12 @@ static int imx_uart_startup(struct uart_port *port)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
|
if (uart_console(&sport->port))
|
||||||
|
sport->rxtl = RXTL_CONSOLE_DEFAULT;
|
||||||
|
else
|
||||||
|
sport->rxtl = RXTL_DEFAULT;
|
||||||
|
|
||||||
|
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
|
||||||
|
|
||||||
/* disable the DREN bit (Data Ready interrupt enable) before
|
/* disable the DREN bit (Data Ready interrupt enable) before
|
||||||
* requesting IRQs
|
* requesting IRQs
|
||||||
@@ -1936,7 +1943,7 @@ static int imx_uart_poll_init(struct uart_port *port)
|
|||||||
if (retval)
|
if (retval)
|
||||||
clk_disable_unprepare(sport->clk_ipg);
|
clk_disable_unprepare(sport->clk_ipg);
|
||||||
|
|
||||||
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
|
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
|
||||||
|
|
||||||
uart_port_lock_irqsave(&sport->port, &flags);
|
uart_port_lock_irqsave(&sport->port, &flags);
|
||||||
|
|
||||||
@@ -2028,7 +2035,7 @@ static int imx_uart_rs485_config(struct uart_port *port, struct ktermios *termio
|
|||||||
/* If the receiver trigger is 0, set it to a default value */
|
/* If the receiver trigger is 0, set it to a default value */
|
||||||
ufcr = imx_uart_readl(sport, UFCR);
|
ufcr = imx_uart_readl(sport, UFCR);
|
||||||
if ((ufcr & UFCR_RXTL_MASK) == 0)
|
if ((ufcr & UFCR_RXTL_MASK) == 0)
|
||||||
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
|
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
|
||||||
imx_uart_start_rx(port);
|
imx_uart_start_rx(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2213,7 +2220,7 @@ imx_uart_console_setup(struct console *co, char *options)
|
|||||||
else
|
else
|
||||||
imx_uart_console_get_options(sport, &baud, &parity, &bits);
|
imx_uart_console_get_options(sport, &baud, &parity, &bits);
|
||||||
|
|
||||||
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT);
|
imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
|
||||||
|
|
||||||
retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
|
retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user