serial: stm32: update PIO transmission
Improves PIO transmission: - Replaces the FIFO filling per character by a filling per blocks of characters, which provides better performances - Replaces the active waiting loop by TX empty interrupt dynamic handling. TXE interrupt is now enabled when data has to be sent (ie when uart_circ is not empty), and inhibited when there is no more data to send (ie when uart_circ is empty). Signed-off-by: Erwan Le Ray <erwan.leray@st.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4cc0ed626f
commit
5d9176edac
@ -300,27 +300,26 @@ static void stm32_transmit_chars_pio(struct uart_port *port)
|
|||||||
struct stm32_port *stm32_port = to_stm32_port(port);
|
struct stm32_port *stm32_port = to_stm32_port(port);
|
||||||
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
|
||||||
struct circ_buf *xmit = &port->state->xmit;
|
struct circ_buf *xmit = &port->state->xmit;
|
||||||
unsigned int isr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (stm32_port->tx_dma_busy) {
|
if (stm32_port->tx_dma_busy) {
|
||||||
stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
|
stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
|
||||||
stm32_port->tx_dma_busy = false;
|
stm32_port->tx_dma_busy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
|
while (!uart_circ_empty(xmit)) {
|
||||||
isr,
|
/* Check that TDR is empty before filling FIFO */
|
||||||
(isr & USART_SR_TXE),
|
if (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE))
|
||||||
10, 100000);
|
break;
|
||||||
|
writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
|
||||||
|
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||||
|
port->icount.tx++;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret)
|
/* rely on TXE irq (mask or unmask) for sending remaining data */
|
||||||
dev_err(port->dev, "tx empty not set\n");
|
if (uart_circ_empty(xmit))
|
||||||
|
stm32_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
|
||||||
stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
|
else
|
||||||
|
stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
|
||||||
writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
|
|
||||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
|
||||||
port->icount.tx++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stm32_transmit_chars_dma(struct uart_port *port)
|
static void stm32_transmit_chars_dma(struct uart_port *port)
|
||||||
|
Loading…
Reference in New Issue
Block a user