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>
This commit is contained in:
Bartosz Golaszewski 2022-12-29 16:50:25 +01:00 коммит произвёл Greg Kroah-Hartman
Родитель 3931b8fdec
Коммит d420fb491c
1 изменённых файлов: 50 добавлений и 44 удалений

Просмотреть файл

@ -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); writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN);
} }
static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done, static int qcom_geni_serial_send_chunk_fifo(struct uart_port *uport,
bool active) unsigned int chunk)
{ {
struct qcom_geni_serial_port *port = to_dev_port(uport); struct qcom_geni_serial_port *port = to_dev_port(uport);
struct circ_buf *xmit = &uport->state->xmit; struct circ_buf *xmit = &uport->state->xmit;
size_t avail; size_t remaining = chunk;
size_t remaining; int i, tail = xmit->tail;
size_t pending;
int i;
u32 status;
u32 irq_en;
unsigned int chunk;
int 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; ) { for (i = 0; i < chunk; ) {
unsigned int tx_bytes; unsigned int tx_bytes;
u8 buf[sizeof(u32)]; 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; 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 * The tx fifo watermark is level triggered and latched. Though we had