tty: serial: qcom-geni-serial: split out the FIFO tx code

qcom_geni_serial_handle_tx() is pretty big, let's move the code that
handles the actual writing of data to a separate function which makes
sense in preparation for introducing a dma variant of handle_tx().

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Link: https://lore.kernel.org/r/20221229155030.418800-10-brgl@bgdev.pl
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index e34fe56..bd91a6a 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -704,53 +704,14 @@ static void qcom_geni_serial_start_rx(struct uart_port *uport)
 	writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
 }
 
-static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
-		bool active)
+static int qcom_geni_serial_send_chunk_fifo(struct uart_port *uport,
+					    unsigned int chunk)
 {
 	struct qcom_geni_serial_port *port = to_dev_port(uport);
 	struct circ_buf *xmit = &uport->state->xmit;
-	size_t avail;
-	size_t remaining;
-	size_t pending;
-	int i;
-	u32 status;
-	u32 irq_en;
-	unsigned int chunk;
-	int tail;
+	size_t remaining = chunk;
+	int i, tail = xmit->tail;
 
-	status = readl(uport->membase + SE_GENI_TX_FIFO_STATUS);
-
-	/* Complete the current tx command before taking newly added data */
-	if (active)
-		pending = port->tx_remaining;
-	else
-		pending = uart_circ_chars_pending(xmit);
-
-	/* All data has been transmitted and acknowledged as received */
-	if (!pending && !status && done) {
-		qcom_geni_serial_stop_tx(uport);
-		goto out_write_wakeup;
-	}
-
-	avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
-	avail *= BYTES_PER_FIFO_WORD;
-
-	tail = xmit->tail;
-	chunk = min(avail, pending);
-	if (!chunk)
-		goto out_write_wakeup;
-
-	if (!port->tx_remaining) {
-		qcom_geni_serial_setup_tx(uport, pending);
-		port->tx_remaining = pending;
-
-		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
-		if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
-			writel(irq_en | M_TX_FIFO_WATERMARK_EN,
-					uport->membase + SE_GENI_M_IRQ_EN);
-	}
-
-	remaining = chunk;
 	for (i = 0; i < chunk; ) {
 		unsigned int tx_bytes;
 		u8 buf[sizeof(u32)];
@@ -772,7 +733,52 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
 		port->tx_remaining -= tx_bytes;
 	}
 
-	xmit->tail = tail;
+	return tail;
+}
+
+static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done,
+		bool active)
+{
+	struct qcom_geni_serial_port *port = to_dev_port(uport);
+	struct circ_buf *xmit = &uport->state->xmit;
+	size_t avail;
+	size_t pending;
+	u32 status;
+	u32 irq_en;
+	unsigned int chunk;
+
+	status = readl(uport->membase + SE_GENI_TX_FIFO_STATUS);
+
+	/* Complete the current tx command before taking newly added data */
+	if (active)
+		pending = port->tx_remaining;
+	else
+		pending = uart_circ_chars_pending(xmit);
+
+	/* All data has been transmitted and acknowledged as received */
+	if (!pending && !status && done) {
+		qcom_geni_serial_stop_tx(uport);
+		goto out_write_wakeup;
+	}
+
+	avail = port->tx_fifo_depth - (status & TX_FIFO_WC);
+	avail *= BYTES_PER_FIFO_WORD;
+
+	chunk = min(avail, pending);
+	if (!chunk)
+		goto out_write_wakeup;
+
+	if (!port->tx_remaining) {
+		qcom_geni_serial_setup_tx(uport, pending);
+		port->tx_remaining = pending;
+
+		irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+		if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
+			writel(irq_en | M_TX_FIFO_WATERMARK_EN,
+					uport->membase + SE_GENI_M_IRQ_EN);
+	}
+
+	xmit->tail = qcom_geni_serial_send_chunk_fifo(uport, chunk);
 
 	/*
 	 * The tx fifo watermark is level triggered and latched. Though we had