From 1788cf6a91d9fa9aa61fc2917afe192c23d67f6a Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Fri, 5 Apr 2024 08:08:23 +0200 Subject: tty: serial: switch from circ_buf to kfifo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch from struct circ_buf to proper kfifo. kfifo provides much better API, esp. when wrap-around of the buffer needs to be taken into account. Look at pl011_dma_tx_refill() or cpm_uart_tx_pump() changes for example. Kfifo API can also fill in scatter-gather DMA structures, so it easier for that use case too. Look at lpuart_dma_tx() for example. Note that not all drivers can be converted to that (like atmel_serial), they handle DMA specially. Note that usb-serial uses kfifo for TX for ages. omap needed a bit more care as it needs to put a char into FIFO to start the DMA transfer when OMAP_DMA_TX_KICK is set. In that case, we have to do kfifo_dma_out_prepare twice: once to find out the tx_size (to find out if it is worths to do DMA at all -- size >= 4), the second time for the actual transfer. All traces of circ_buf are removed from serial_core.h (and its struct uart_state). Signed-off-by: Jiri Slaby (SUSE) Cc: Al Cooper Cc: Matthias Brugger Cc: AngeloGioacchino Del Regno Cc: Kumaravel Thiagarajan Cc: Tharun Kumar P Cc: Russell King Cc: Vineet Gupta Cc: Richard Genoud Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Claudiu Beznea Cc: Alexander Shiyan Cc: Baruch Siach Cc: Maciej W. Rozycki Cc: Shawn Guo Cc: Sascha Hauer Cc: Fabio Estevam Cc: Neil Armstrong Cc: Kevin Hilman Cc: Jerome Brunet Cc: Martin Blumenstingl Cc: Taichi Sugaya Cc: Takao Orito Cc: Bjorn Andersson Cc: Konrad Dybcio Cc: Pali Rohár Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Aneesh Kumar K.V Cc: Naveen N. Rao Cc: Manivannan Sadhasivam Cc: Krzysztof Kozlowski Cc: Alim Akhtar Cc: Laxman Dewangan Cc: Thierry Reding Cc: Jonathan Hunter Cc: Orson Zhai Cc: Baolin Wang Cc: Chunyan Zhang Cc: Patrice Chotard Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: David S. Miller Cc: Hammer Hsieh Cc: Peter Korsgaard Cc: Timur Tabi Cc: Michal Simek Cc: Sumit Semwal Cc: Christian König Link: https://lore.kernel.org/r/20240405060826.2521-13-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/tty/serial/meson_uart.c') diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 6feac459c0cf..4587ed4d4d5d 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -141,8 +141,8 @@ static void meson_uart_shutdown(struct uart_port *port) static void meson_uart_start_tx(struct uart_port *port) { - struct circ_buf *xmit = &port->state->xmit; - unsigned int ch; + struct tty_port *tport = &port->state->port; + unsigned char ch; u32 val; if (uart_tx_stopped(port)) { @@ -158,21 +158,20 @@ static void meson_uart_start_tx(struct uart_port *port) continue; } - if (uart_circ_empty(xmit)) + if (!uart_fifo_get(port, &ch)) break; - ch = xmit->buf[xmit->tail]; writel(ch, port->membase + AML_UART_WFIFO); uart_xmit_advance(port, 1); } - if (!uart_circ_empty(xmit)) { + if (!kfifo_is_empty(&tport->xmit_fifo)) { val = readl(port->membase + AML_UART_CONTROL); val |= AML_UART_TX_INT_EN; writel(val, port->membase + AML_UART_CONTROL); } - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) uart_write_wakeup(port); } -- cgit v1.2.3-59-g8ed1b From 35fad98ed25ab9e08c4363f0f74efd612c8eb185 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Tue, 16 Apr 2024 07:48:25 +0200 Subject: serial: meson+qcom: don't advance the kfifo twice Marek reports, that the -next commit 1788cf6a91d9 (tty: serial: switch from circ_buf to kfifo) broke meson_uart and qcom_geni_serial. The commit mistakenly advanced the kfifo twice: once by uart_fifo_get()/kfifo_out() and second time by uart_xmit_advance(). To advance the fifo only once, drop the superfluous uart_xmit_advance() from both. To count the TX statistics properly, use uart_fifo_out() in qcom_geni_serial (meson_uart_start_tx() already uses that). I checked all other uses of uart_xmit_advance() and they appear correct: either they are finishing DMA transfers or are after peek/linear_ptr (i.e. they do not advance fifo). Signed-off-by: Jiri Slaby (SUSE) Reported-by: Marek Szyprowski Fixes: 1788cf6a91d9 ("tty: serial: switch from circ_buf to kfifo") Cc: Neil Armstrong Cc: Kevin Hilman Cc: Jerome Brunet Cc: Martin Blumenstingl Link: https://lore.kernel.org/r/20240416054825.6211-1-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/meson_uart.c | 1 - drivers/tty/serial/qcom_geni_serial.c | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/tty/serial/meson_uart.c') diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 4587ed4d4d5d..8eb586ac3b0d 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -162,7 +162,6 @@ static void meson_uart_start_tx(struct uart_port *port) break; writel(ch, port->membase + AML_UART_WFIFO); - uart_xmit_advance(port, 1); } if (!kfifo_is_empty(&tport->xmit_fifo)) { diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 7814982f1921..2bd25afe0d92 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -855,7 +855,6 @@ static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport, unsigned int chunk) { struct qcom_geni_serial_port *port = to_dev_port(uport); - struct tty_port *tport = &uport->state->port; unsigned int tx_bytes, remaining = chunk; u8 buf[BYTES_PER_FIFO_WORD]; @@ -863,8 +862,7 @@ static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport, memset(buf, 0, sizeof(buf)); tx_bytes = min(remaining, BYTES_PER_FIFO_WORD); - tx_bytes = kfifo_out(&tport->xmit_fifo, buf, tx_bytes); - uart_xmit_advance(uport, tx_bytes); + tx_bytes = uart_fifo_out(uport, buf, tx_bytes); iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1); -- cgit v1.2.3-59-g8ed1b