Commit 2d141e68 authored by Jiri Slaby (SUSE)'s avatar Jiri Slaby (SUSE) Committed by Greg Kroah-Hartman
Browse files

tty: serial: use uart_port_tx() helper



uart_port_tx() is a new helper to send characters to the device. Use it
in these drivers.

Cc: Tobias Klauser <tklauser@distanz.ch>
Cc: Richard Genoud <richard.genoud@gmail.com>
Cc: Nicolas Ferre <nicolas.ferre@microchip.com>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: Claudiu Beznea <claudiu.beznea@microchip.com>
Cc: Vladimir Zapolskiy <vz@mleia.com>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: "Andreas Färber" <afaerber@suse.de>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarJiri Slaby (SUSE) <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20221004104927.14361-3-jirislaby@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8275b48b
Loading
Loading
Loading
Loading
+5 −24
Original line number Diff line number Diff line
@@ -247,31 +247,12 @@ static void altera_uart_rx_chars(struct uart_port *port)

static void altera_uart_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;
	u8 ch;

	if (port->x_char) {
		/* Send special char - probably flow control */
		altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG);
		port->x_char = 0;
		port->icount.tx++;
		return;
	}

	while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
	       ALTERA_UART_STATUS_TRDY_MSK) {
		if (xmit->head == xmit->tail)
			break;
		altera_uart_writel(port, xmit->buf[xmit->tail],
		       ALTERA_UART_TXDATA_REG);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit))
		altera_uart_stop_tx(port);
	uart_port_tx(port, ch,
		altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
		                ALTERA_UART_STATUS_TRDY_MSK,
		altera_uart_writel(port, ch, ALTERA_UART_TXDATA_REG));
}

static irqreturn_t altera_uart_interrupt(int irq, void *data)
+6 −22
Original line number Diff line number Diff line
@@ -824,30 +824,14 @@ static void atmel_rx_chars(struct uart_port *port)
 */
static void atmel_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;
	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
	bool pending;
	u8 ch;

	if (port->x_char &&
	    (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) {
		atmel_uart_write_char(port, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
	}
	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
		return;

	while (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY) {
		atmel_uart_write_char(port, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if (uart_circ_empty(xmit))
			break;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (!uart_circ_empty(xmit)) {
	pending = uart_port_tx(port, ch,
		atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY,
		atmel_uart_write_char(port, ch));
	if (pending) {
		/* we still have characters to transmit, so we should continue
		 * transmitting them when TX is ready, regardless of
		 * mode or duplexity
+5 −25
Original line number Diff line number Diff line
@@ -742,32 +742,12 @@ static int lpuart32_poll_get_char(struct uart_port *port)

static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
{
	struct circ_buf *xmit = &sport->port.state->xmit;

	if (sport->port.x_char) {
		writeb(sport->port.x_char, sport->port.membase + UARTDR);
		sport->port.icount.tx++;
		sport->port.x_char = 0;
		return;
	}

	if (lpuart_stopped_or_empty(&sport->port)) {
		lpuart_stop_tx(&sport->port);
		return;
	}

	while (!uart_circ_empty(xmit) &&
		(readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size)) {
		writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		sport->port.icount.tx++;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&sport->port);
	struct uart_port *port = &sport->port;
	u8 ch;

	if (uart_circ_empty(xmit))
		lpuart_stop_tx(&sport->port);
	uart_port_tx(port, ch,
		readb(port->membase + UARTTCFIFO) < sport->txfifo_size,
		writeb(ch, port->membase + UARTDR));
}

static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
+4 −32
Original line number Diff line number Diff line
@@ -95,7 +95,6 @@
#define ASCFSTAT_TXFFLMASK	0x3F00
#define ASCFSTAT_TXFREEMASK	0x3F000000

static void lqasc_tx_chars(struct uart_port *port);
static struct ltq_uart_port *lqasc_port[MAXPORTS];
static struct uart_driver lqasc_reg;

@@ -151,9 +150,12 @@ lqasc_start_tx(struct uart_port *port)
{
	unsigned long flags;
	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
	u8 ch;

	spin_lock_irqsave(&ltq_port->lock, flags);
	lqasc_tx_chars(port);
	uart_port_tx(port, ch,
		lqasc_tx_ready(port),
		writeb(ch, port->membase + LTQ_ASC_TBUF));
	spin_unlock_irqrestore(&ltq_port->lock, flags);
	return;
}
@@ -226,36 +228,6 @@ lqasc_rx_chars(struct uart_port *port)
	return 0;
}

static void
lqasc_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;
	if (uart_tx_stopped(port)) {
		lqasc_stop_tx(port);
		return;
	}

	while (lqasc_tx_ready(port)) {
		if (port->x_char) {
			writeb(port->x_char, port->membase + LTQ_ASC_TBUF);
			port->icount.tx++;
			port->x_char = 0;
			continue;
		}

		if (uart_circ_empty(xmit))
			break;

		writeb(port->state->xmit.buf[port->state->xmit.tail],
			port->membase + LTQ_ASC_TBUF);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);
}

static irqreturn_t
lqasc_tx_int(int irq, void *_port)
{
+4 −29
Original line number Diff line number Diff line
@@ -276,8 +276,6 @@ static void __serial_lpc32xx_rx(struct uart_port *port)
	tty_flip_buffer_push(tport);
}

static void serial_lpc32xx_stop_tx(struct uart_port *port);

static bool serial_lpc32xx_tx_ready(struct uart_port *port)
{
	u32 level = readl(LPC32XX_HSUART_LEVEL(port->membase));
@@ -287,34 +285,11 @@ static bool serial_lpc32xx_tx_ready(struct uart_port *port)

static void __serial_lpc32xx_tx(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;

	if (port->x_char) {
		writel((u32)port->x_char, LPC32XX_HSUART_FIFO(port->membase));
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
		goto exit_tx;

	/* Transfer data */
	while (serial_lpc32xx_tx_ready(port)) {
		writel((u32) xmit->buf[xmit->tail],
		       LPC32XX_HSUART_FIFO(port->membase));
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if (uart_circ_empty(xmit))
			break;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);
	u8 ch;

exit_tx:
	if (uart_circ_empty(xmit))
		serial_lpc32xx_stop_tx(port);
	uart_port_tx(port, ch,
		serial_lpc32xx_tx_ready(port),
		writel(ch, LPC32XX_HSUART_FIFO(port->membase)));
}

static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id)
Loading