]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
serial: qcom_geni: Fix RX DMA stall when SE_DMA_RX_LEN_IN is zero
authorViken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Thu, 28 May 2026 17:18:07 +0000 (22:48 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 12 Jun 2026 09:51:28 +0000 (11:51 +0200)
In qcom_geni_serial_handle_rx_dma(), geni_se_rx_dma_unprep() clears
port->rx_dma_addr before SE_DMA_RX_LEN_IN is read. If the register is zero,
for example when the RX stale counter fires on an idle line, the handler
returns without calling geni_se_rx_dma_prep().

The next RX DMA interrupt then hits the !port->rx_dma_addr guard and
returns immediately, so the RX DMA buffer is never rearmed and later input
is lost.

Keep the handler on the rearm path when rx_in is zero. Warn about the
unexpected zero-length DMA completion, skip received-data handling, and
always call geni_se_rx_dma_prep().

Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA")
Cc: stable@vger.kernel.org
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Link: https://patch.msgid.link/20260528-serial-rx-0-byte-fix-v2-1-b4195cfe342f@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/qcom_geni_serial.c

index d81b539cff7f052c520afb842bce4186c3761370..7ead87b4eb65b207673b693f031af49c6816546e 100644 (file)
@@ -905,12 +905,9 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop)
        port->rx_dma_addr = 0;
 
        rx_in = readl(uport->membase + SE_DMA_RX_LEN_IN);
-       if (!rx_in) {
-               dev_warn(uport->dev, "serial engine reports 0 RX bytes in!\n");
-               return;
-       }
-
-       if (!drop)
+       if (!rx_in)
+               dev_warn_ratelimited(uport->dev, "serial engine reports 0 RX bytes in!\n");
+       else if (!drop)
                handle_rx_uart(uport, rx_in);
 
        ret = geni_se_rx_dma_prep(&port->se, port->rx_buf,