tty: serial: use uart_port_tx() helper
authorJiri Slaby (SUSE) <jirislaby@kernel.org>
Tue, 4 Oct 2022 10:49:26 +0000 (12:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Nov 2022 02:32:40 +0000 (03:32 +0100)
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: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20221004104927.14361-3-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
12 files changed:
drivers/tty/serial/altera_uart.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/lantiq.c
drivers/tty/serial/lpc32xx_hs.c
drivers/tty/serial/mcf.c
drivers/tty/serial/mpc52xx_uart.c
drivers/tty/serial/mps2-uart.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/owl-uart.c
drivers/tty/serial/sa1100.c
drivers/tty/serial/vt8500_serial.c

index 82f2790de28d198e5611f571cfadd2610505bcf0..316074bb23e9fb46d1c3cd66172ddf4ee4068296 100644 (file)
@@ -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;
-
-       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);
+       u8 ch;
 
-       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)
index bd07f79a2df91b2263df5d0f1f17cbb1343e304f..a6b4d30c5888d8e9f485af2483d2a75016f25e83 100644 (file)
@@ -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
index 67fa113f77d475a621bc53bec3b33752abc0ad2a..d811eda1844e797bb412eba54e110398b42f1acb 100644 (file)
@@ -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)
index c892f3c7d1abc1b6f2ee7e2755e09f01db20de60..a58e9277dfad8752b10af8ca5bd8ad7383984531 100644 (file)
@@ -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)
 {
index ed47f476833831bc7eb5cd57f23cea22ac04a523..b38fe4728c26490dcd1e4124add07894ec5b8645 100644 (file)
@@ -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)
index b1cd9a76dd93bc4d49c8d6b1d10d3f8ba4168dc1..3239babe12a4edb954fe0736280d6dfc4d6fddb6 100644 (file)
@@ -327,34 +327,16 @@ static void mcf_rx_chars(struct mcf_uart *pp)
 static void mcf_tx_chars(struct mcf_uart *pp)
 {
        struct uart_port *port = &pp->port;
-       struct circ_buf *xmit = &port->state->xmit;
-
-       if (port->x_char) {
-               /* Send special char - probably flow control */
-               writeb(port->x_char, port->membase + MCFUART_UTB);
-               port->x_char = 0;
-               port->icount.tx++;
-               return;
-       }
-
-       while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) {
-               if (uart_circ_empty(xmit))
-                       break;
-               writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB);
-               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
-               port->icount.tx++;
-       }
+       bool pending;
+       u8 ch;
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(port);
+       pending = uart_port_tx(port, ch,
+               readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY,
+               writeb(ch, port->membase + MCFUART_UTB));
 
-       if (uart_circ_empty(xmit)) {
-               mcf_stop_tx(port);
-               /* Disable TX to negate RTS automatically */
-               if (port->rs485.flags & SER_RS485_ENABLED)
-                       writeb(MCFUART_UCR_TXDISABLE,
-                               port->membase + MCFUART_UCR);
-       }
+       /* Disable TX to negate RTS automatically */
+       if (!pending && (port->rs485.flags & SER_RS485_ENABLED))
+               writeb(MCFUART_UCR_TXDISABLE, port->membase + MCFUART_UCR);
 }
 
 /****************************************************************************/
index 73362d4bc45d3cd5daee86cbafdea1a516f0584d..384ca195e3d5d24eb0d8fc332d28981e2c2ea730 100644 (file)
@@ -1428,42 +1428,11 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
 static inline bool
 mpc52xx_uart_int_tx_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
-
-       /* Process out of band chars */
-       if (port->x_char) {
-               psc_ops->write_char(port, port->x_char);
-               port->icount.tx++;
-               port->x_char = 0;
-               return true;
-       }
-
-       /* Nothing to do ? */
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-               mpc52xx_uart_stop_tx(port);
-               return false;
-       }
-
-       /* Send chars */
-       while (psc_ops->raw_tx_rdy(port)) {
-               psc_ops->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;
-       }
-
-       /* Wake up */
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(port);
-
-       /* Maybe we're done after all */
-       if (uart_circ_empty(xmit)) {
-               mpc52xx_uart_stop_tx(port);
-               return false;
-       }
+       u8 ch;
 
-       return true;
+       return uart_port_tx(port, ch,
+               psc_ops->raw_tx_rdy(port),
+               psc_ops->write_char(port, ch));
 }
 
 static irqreturn_t
index 2e3e6cf1681784c484d6a8653dbda5f9670ca122..860d161fa59484f85fddefcbd821c08d9029d1e9 100644 (file)
@@ -129,29 +129,11 @@ static void mps2_uart_stop_tx(struct uart_port *port)
 
 static void mps2_uart_tx_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
-
-       while (!(mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)) {
-               if (port->x_char) {
-                       mps2_uart_write8(port, port->x_char, UARTn_DATA);
-                       port->x_char = 0;
-                       port->icount.tx++;
-                       continue;
-               }
-
-               if (uart_circ_empty(xmit) || uart_tx_stopped(port))
-                       break;
-
-               mps2_uart_write8(port, xmit->buf[xmit->tail], UARTn_DATA);
-               xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE;
-               port->icount.tx++;
-       }
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(port);
+       u8 ch;
 
-       if (uart_circ_empty(xmit))
-               mps2_uart_stop_tx(port);
+       uart_port_tx(port, ch,
+               mps2_uart_tx_empty(port),
+               mps2_uart_write8(port, ch, UARTn_DATA));
 }
 
 static void mps2_uart_start_tx(struct uart_port *port)
index d21a4f3ef2fe614de096df2ac694ee102a1878fc..ef6e7bb6105cad2b0463eabef2060ae4043fe9cc 100644 (file)
@@ -569,6 +569,8 @@ static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size)
 static void mxs_auart_tx_chars(struct mxs_auart_port *s)
 {
        struct circ_buf *xmit = &s->port.state->xmit;
+       bool pending;
+       u8 ch;
 
        if (auart_dma_enabled(s)) {
                u32 i = 0;
@@ -603,31 +605,13 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s)
                return;
        }
 
-
-       while (!(mxs_read(s, REG_STAT) & AUART_STAT_TXFF)) {
-               if (s->port.x_char) {
-                       s->port.icount.tx++;
-                       mxs_write(s->port.x_char, s, REG_DATA);
-                       s->port.x_char = 0;
-                       continue;
-               }
-               if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
-                       s->port.icount.tx++;
-                       mxs_write(xmit->buf[xmit->tail], s, REG_DATA);
-                       xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               } else
-                       break;
-       }
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(&s->port);
-
-       if (uart_circ_empty(&(s->port.state->xmit)))
-               mxs_clr(AUART_INTR_TXIEN, s, REG_INTR);
-       else
+       pending = uart_port_tx(&s->port, ch,
+               !(mxs_read(s, REG_STAT) & AUART_STAT_TXFF),
+               mxs_write(ch, s, REG_DATA));
+       if (pending)
                mxs_set(AUART_INTR_TXIEN, s, REG_INTR);
-
-       if (uart_tx_stopped(&s->port))
-               mxs_auart_stop_tx(&s->port);
+       else
+               mxs_clr(AUART_INTR_TXIEN, s, REG_INTR);
 }
 
 static void mxs_auart_rx_char(struct mxs_auart_port *s)
index fde39cc1145db53caf5f562abe0db63c037935c6..e99970a9437ff2cf7d6c3245c3ec46259fe0d89d 100644 (file)
@@ -181,35 +181,11 @@ static void owl_uart_start_tx(struct uart_port *port)
 
 static void owl_uart_send_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
-       unsigned int ch;
-
-       if (port->x_char) {
-               while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU))
-                       cpu_relax();
-               owl_uart_write(port, port->x_char, OWL_UART_TXDAT);
-               port->icount.tx++;
-               port->x_char = 0;
-       }
-
-       if (uart_tx_stopped(port))
-               return;
-
-       while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) {
-               if (uart_circ_empty(xmit))
-                       break;
+       u8 ch;
 
-               ch = xmit->buf[xmit->tail];
-               owl_uart_write(port, ch, OWL_UART_TXDAT);
-               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))
-               owl_uart_stop_tx(port);
+       uart_port_tx(port, ch,
+               !(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU),
+               owl_uart_write(port, ch, OWL_UART_TXDAT));
 }
 
 static void owl_uart_receive_chars(struct uart_port *port)
index dd9e3253cab4487d7774528ed87f3a1a35de634e..55107bbc00ceb2ea9870ee7d7062689a5c719982 100644 (file)
@@ -228,14 +228,7 @@ sa1100_rx_chars(struct sa1100_port *sport)
 
 static void sa1100_tx_chars(struct sa1100_port *sport)
 {
-       struct circ_buf *xmit = &sport->port.state->xmit;
-
-       if (sport->port.x_char) {
-               UART_PUT_CHAR(sport, sport->port.x_char);
-               sport->port.icount.tx++;
-               sport->port.x_char = 0;
-               return;
-       }
+       u8 ch;
 
        /*
         * Check the modem control lines before
@@ -243,28 +236,9 @@ static void sa1100_tx_chars(struct sa1100_port *sport)
         */
        sa1100_mctrl_check(sport);
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
-               sa1100_stop_tx(&sport->port);
-               return;
-       }
-
-       /*
-        * Tried using FIFO (not checking TNF) for fifo fill:
-        * still had the '4 bytes repeated' problem.
-        */
-       while (UART_GET_UTSR1(sport) & UTSR1_TNF) {
-               UART_PUT_CHAR(sport, xmit->buf[xmit->tail]);
-               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               sport->port.icount.tx++;
-               if (uart_circ_empty(xmit))
-                       break;
-       }
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(&sport->port);
-
-       if (uart_circ_empty(xmit))
-               sa1100_stop_tx(&sport->port);
+       uart_port_tx(&sport->port, ch,
+                       UART_GET_UTSR1(sport) & UTSR1_TNF,
+                       UART_PUT_CHAR(sport, ch));
 }
 
 static irqreturn_t sa1100_int(int irq, void *dev_id)
index 10fbdb09965f3f63aadccb2ad376728e793600f1..deedb6513160690919655a911ac051f8b03cd509 100644 (file)
@@ -196,33 +196,11 @@ static unsigned int vt8500_tx_empty(struct uart_port *port)
 
 static void handle_tx(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       u8 ch;
 
-       if (port->x_char) {
-               writeb(port->x_char, port->membase + VT8500_TXFIFO);
-               port->icount.tx++;
-               port->x_char = 0;
-       }
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-               vt8500_stop_tx(port);
-               return;
-       }
-
-       while (vt8500_tx_empty(port)) {
-               if (uart_circ_empty(xmit))
-                       break;
-
-               writeb(xmit->buf[xmit->tail], port->membase + VT8500_TXFIFO);
-
-               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))
-               vt8500_stop_tx(port);
+       uart_port_tx(port, ch,
+               vt8500_tx_empty(port),
+               writeb(ch, port->membase + VT8500_TXFIFO));
 }
 
 static void vt8500_start_tx(struct uart_port *port)