[PATCH] serial: msm_geni: validate RX data with IRQ status
Casey Connolly
casey.connolly at linaro.org
Tue Jun 30 09:57:13 CEST 2026
Hi Balaji,
On 6/29/26 13:31, Balaji Selvanathan wrote:
> The GENI UART hardware can retain stale data in the RX FIFO.
> The msm_serial_pending() function was reporting this stale data as
> pending input, causing U-Boot to incorrectly assume a key press and
> stop at the CLI prompt instead of continuing the boot process.
>
> Add IRQ status validation to distinguish between legitimate received
> data and stale FIFO contents. Check the Secondary IRQ status register
> for RX watermark or last flags before reporting pending data. If the
> FIFO contains data but no valid IRQ flags are set, ignore it as stale.
Taking a look here compared to the Linux polling mode driver I don't
think this is the right way to solve this.
In qcom_geni_serial_stop_rx_fifo() in Linux after clearing the RX IRQs
the cancel command is sent (and polled on) and then if S_RX_FIFO_LAST_EN
is set the FIFO is drained.
So the right fix here for U-Boot would be to do something similar in
msm_geni_serial_setup_rx(), send a cancel rather than an abort, wait for
it to complete (or timeout), drain the fifo, and then send an abort if
S_GENI_CMD_ACTIVE is still set to fully reset it.
so NAK, please solve this properly by fixing the init sequence.
>
> Signed-off-by: Balaji Selvanathan <balaji.selvanathan at oss.qualcomm.com>
> ---
> drivers/serial/serial_msm_geni.c | 27 ++++++++++++++++++++++-----
> 1 file changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c
> index 3dca581f68f..6d30f150966 100644
> --- a/drivers/serial/serial_msm_geni.c
> +++ b/drivers/serial/serial_msm_geni.c
> @@ -424,13 +424,30 @@ static int msm_serial_getc(struct udevice *dev)
> static int msm_serial_pending(struct udevice *dev, bool input)
> {
> struct msm_serial_data *priv = dev_get_priv(dev);
> -
> - if (input)
> - return readl(priv->base + SE_GENI_RX_FIFO_STATUS) &
> - RX_FIFO_WC_MSK;
> - else
> + u32 rx_fifo_status, s_irq_status;
> + int result;
> +
> + if (input) {
> + rx_fifo_status = readl(priv->base + SE_GENI_RX_FIFO_STATUS);
> + result = rx_fifo_status & RX_FIFO_WC_MSK;
> +
> + /*
> + * Validate RX data with IRQ status
> + * Only report pending data if valid RX IRQ indicators are set.
What does this mean "valid RX IRQ indicators"??? This comment is fluff,
use better variable names (result -> word_count)
> + */
> + if (result) {
if (word_count > 0)> + s_irq_status = readl(priv->base +
SE_GENI_S_IRQ_STATUS);
> +
> + if (!(s_irq_status & (S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN))) {
> + /* No valid RX IRQ, ignore stale data */
> + return 0;
> + }
> + }
> + return result;
> + } else {
> return readl(priv->base + SE_GENI_TX_FIFO_STATUS) &
> TX_FIFO_WC_MSK;
> + }
>
> return 0;
> }
>
> ---
> base-commit: 6902fb4c17faa375003124c451c2550deab5463d
> change-id: 20260629-uart-e07d893e4508
>
> Best regards,
More information about the U-Boot
mailing list