merged. Bruce
In message: Re: [linux-yocto] [PATCH] tty: serial: fsl_lpuart: don't break the on-going transfer when global reset on 13/03/2023 Wang, Xiaolei wrote: > Hi bruce > > Please help merge this patch to v5.15/standard/nxp-sdk-5.15/nxp-soc and v5.15/ > standard/preempt-rt/nxp-sdk-5.15/nxp-soc branches > > thanks > xiaolei > ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ > From: [email protected] <[email protected]> > on behalf of Xiaolei Wang via lists.yoctoproject.org <xiaolei.wang= > [email protected]> > Sent: Monday, March 13, 2023 9:44 PM > To: [email protected] <[email protected]> > Cc: [email protected] <[email protected]> > Subject: [linux-yocto] [PATCH] tty: serial: fsl_lpuart: don't break the > on-going transfer when global reset > > From: Sherry Sun <[email protected]> > > commit 76bad3f88750f8cc465c489e6846249e0bc3d8f5 from upstream. > > lpuart_global_reset() shouldn't break the on-going transmit engine, need > to recover the on-going data transfer after reset. > > This can help earlycon here, since commit 60f361722ad2 ("serial: > fsl_lpuart: Reset prior to registration") moved lpuart_global_reset() > before uart_add_one_port(), earlycon is writing during global reset, > as global reset will disable the TX and clear the baud rate register, > which caused the earlycon cannot work any more after reset, needs to > restore the baud rate and re-enable the transmitter to recover the > earlycon write. > > Also move the lpuart_global_reset() down, then we can reuse the > lpuart32_tx_empty() without declaration. > > Fixes: bd5305dcabbc ("tty: serial: fsl_lpuart: do software reset for imx7ulp > and imx8qxp") > Signed-off-by: Sherry Sun <[email protected]> > Link: https://lore.kernel.org/r/[email protected] > Signed-off-by: Greg Kroah-Hartman <[email protected]> > Signed-off-by: Xiaolei Wang <[email protected]> > --- > drivers/tty/serial/fsl_lpuart.c | 75 +++++++++++++++++++++------------ > 1 file changed, 48 insertions(+), 27 deletions(-) > > diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c > index 3f8fe874905d..5eae048950b5 100644 > --- a/drivers/tty/serial/fsl_lpuart.c > +++ b/drivers/tty/serial/fsl_lpuart.c > @@ -433,33 +433,6 @@ static unsigned int lpuart_get_baud_clk_rate(struct > lpuart_port *sport) > #define lpuart_enable_clks(x) __lpuart_enable_clks(x, true) > #define lpuart_disable_clks(x) __lpuart_enable_clks(x, false) > > -static int lpuart_global_reset(struct lpuart_port *sport) > -{ > - struct uart_port *port = &sport->port; > - void __iomem *global_addr; > - int ret; > - > - if (uart_console(port)) > - return 0; > - > - ret = clk_prepare_enable(sport->ipg_clk); > - if (ret) { > - dev_err(sport->port.dev, "failed to enable uart ipg clk: > %d\n", > ret); > - return ret; > - } > - > - if (is_imx7ulp_lpuart(sport) || is_imx8ulp_lpuart(sport) || > is_imx8qxp_lpuart(sport)) { > - global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF; > - writel(UART_GLOBAL_RST, global_addr); > - usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); > - writel(0, global_addr); > - usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); > - } > - > - clk_disable_unprepare(sport->ipg_clk); > - return 0; > -} > - > static void lpuart_stop_tx(struct uart_port *port) > { > unsigned char temp; > @@ -2845,6 +2818,54 @@ static int lpuart_attach_pd(struct device *dev) > return 0; > } > > +static int lpuart_global_reset(struct lpuart_port *sport) > +{ > + struct uart_port *port = &sport->port; > + void __iomem *global_addr; > + unsigned long ctrl, bd; > + unsigned int val = 0; > + int ret; > + > + ret = clk_prepare_enable(sport->ipg_clk); > + if (ret) { > + dev_err(sport->port.dev, "failed to enable uart ipg clk: > %d\n", > ret); > + return ret; > + } > + > + if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) { > + /* > + * If the transmitter is used by earlycon, wait for transmit > engine to > + * complete and then reset. > + */ > + ctrl = lpuart32_read(port, UARTCTRL); > + if (ctrl & UARTCTRL_TE) { > + bd = lpuart32_read(&sport->port, UARTBAUD); > + if (read_poll_timeout(lpuart32_tx_empty, val, val, 1, > 100000, false, > + port)) { > + dev_warn(sport->port.dev, > + "timeout waiting for transmit engine > to > complete\n"); > + clk_disable_unprepare(sport->ipg_clk); > + return 0; > + } > + } > + > + global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF; > + writel(UART_GLOBAL_RST, global_addr); > + usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); > + writel(0, global_addr); > + usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); > + > + /* Recover the transmitter for earlycon. */ > + if (ctrl & UARTCTRL_TE) { > + lpuart32_write(port, bd, UARTBAUD); > + lpuart32_write(port, ctrl, UARTCTRL); > + } > + > > } > + > + clk_disable_unprepare(sport->ipg_clk); > + return 0; > +} > + > static int lpuart_probe(struct platform_device *pdev) > { > const struct lpuart_soc_data *sdata = > of_device_get_match_data(&pdev-> > dev); > -- > 2.25.1 >
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#12259): https://lists.yoctoproject.org/g/linux-yocto/message/12259 Mute This Topic: https://lists.yoctoproject.org/mt/97580546/21656 Group Owner: [email protected] Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/leave/6687884/21656/624485779/xyzzy [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
