tty: serial: switch from circ_buf to kfifo
authorJiri Slaby (SUSE) <jirislaby@kernel.org>
Fri, 5 Apr 2024 06:08:23 +0000 (08:08 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Apr 2024 13:28:03 +0000 (15:28 +0200)
Switch from struct circ_buf to proper kfifo. kfifo provides much better
API, esp. when wrap-around of the buffer needs to be taken into account.
Look at pl011_dma_tx_refill() or cpm_uart_tx_pump() changes for example.

Kfifo API can also fill in scatter-gather DMA structures, so it easier
for that use case too. Look at lpuart_dma_tx() for example. Note that
not all drivers can be converted to that (like atmel_serial), they
handle DMA specially.

Note that usb-serial uses kfifo for TX for ages.

omap needed a bit more care as it needs to put a char into FIFO to start
the DMA transfer when OMAP_DMA_TX_KICK is set. In that case, we have to
do kfifo_dma_out_prepare twice: once to find out the tx_size (to find
out if it is worths to do DMA at all -- size >= 4), the second time for
the actual transfer.

All traces of circ_buf are removed from serial_core.h (and its struct
uart_state).

Signed-off-by: Jiri Slaby (SUSE) <jirislaby@kernel.org>
Cc: Al Cooper <alcooperx@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: Kumaravel Thiagarajan <kumaravel.thiagarajan@microchip.com>
Cc: Tharun Kumar P <tharunkumar.pasumarthi@microchip.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Vineet Gupta <vgupta@kernel.org>
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@tuxon.dev>
Cc: Alexander Shiyan <shc_work@mail.ru>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Maciej W. Rozycki <macro@orcam.me.uk>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Cc: Taichi Sugaya <sugaya.taichi@socionext.com>
Cc: Takao Orito <orito.takao@socionext.com>
Cc: Bjorn Andersson <andersson@kernel.org>
Cc: Konrad Dybcio <konrad.dybcio@linaro.org>
Cc: Pali Rohár <pali@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
Cc: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Cc: Alim Akhtar <alim.akhtar@samsung.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Orson Zhai <orsonzhai@gmail.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Chunyan Zhang <zhang.lyra@gmail.com>
Cc: Patrice Chotard <patrice.chotard@foss.st.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Hammer Hsieh <hammerh0314@gmail.com>
Cc: Peter Korsgaard <jacmet@sunsite.dk>
Cc: Timur Tabi <timur@kernel.org>
Cc: Michal Simek <michal.simek@amd.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Link: https://lore.kernel.org/r/20240405060826.2521-13-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
59 files changed:
drivers/tty/serial/8250/8250_bcm7271.c
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_dma.c
drivers/tty/serial/8250/8250_exar.c
drivers/tty/serial/8250/8250_mtk.c
drivers/tty/serial/8250/8250_omap.c
drivers/tty/serial/8250/8250_pci1xxxx.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/ar933x_uart.c
drivers/tty/serial/arc_uart.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/clps711x.c
drivers/tty/serial/cpm_uart.c
drivers/tty/serial/digicolor-usart.c
drivers/tty/serial/dz.c
drivers/tty/serial/fsl_linflexuart.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/icom.c
drivers/tty/serial/imx.c
drivers/tty/serial/ip22zilog.c
drivers/tty/serial/jsm/jsm_cls.c
drivers/tty/serial/jsm/jsm_neo.c
drivers/tty/serial/max3100.c
drivers/tty/serial/max310x.c
drivers/tty/serial/men_z135_uart.c
drivers/tty/serial/meson_uart.c
drivers/tty/serial/milbeaut_usio.c
drivers/tty/serial/msm_serial.c
drivers/tty/serial/mvebu-uart.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/pch_uart.c
drivers/tty/serial/pic32_uart.c
drivers/tty/serial/pmac_zilog.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/rda-uart.c
drivers/tty/serial/samsung_tty.c
drivers/tty/serial/sb1250-duart.c
drivers/tty/serial/sc16is7xx.c
drivers/tty/serial/sccnxp.c
drivers/tty/serial/serial-tegra.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/serial_port.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sprd_serial.c
drivers/tty/serial/st-asc.c
drivers/tty/serial/stm32-usart.c
drivers/tty/serial/sunhv.c
drivers/tty/serial/sunplus-uart.c
drivers/tty/serial/sunsab.c
drivers/tty/serial/sunsu.c
drivers/tty/serial/sunzilog.c
drivers/tty/serial/tegra-tcu.c
drivers/tty/serial/timbuart.c
drivers/tty/serial/uartlite.c
drivers/tty/serial/ucc_uart.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/serial/zs.c
include/linux/serial_core.h

index 5daa38d9c64e01d32cb1c10e48da065998dfbaa3..de270863eb5e14961930221bb36831425972e0f0 100644 (file)
@@ -413,20 +413,18 @@ static int stop_tx_dma(struct uart_8250_port *p)
 static int brcmuart_tx_dma(struct uart_8250_port *p)
 {
        struct brcmuart_priv *priv = p->port.private_data;
-       struct circ_buf *xmit = &p->port.state->xmit;
+       struct tty_port *tport = &p->port.state->port;
        u32 tx_size;
 
        if (uart_tx_stopped(&p->port) || priv->tx_running ||
-               uart_circ_empty(xmit)) {
+               kfifo_is_empty(&tport->xmit_fifo)) {
                return 0;
        }
-       tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
 
        priv->dma.tx_err = 0;
-       memcpy(priv->tx_buf, &xmit->buf[xmit->tail], tx_size);
-       uart_xmit_advance(&p->port, tx_size);
+       tx_size = uart_fifo_out(&p->port, priv->tx_buf, UART_XMIT_SIZE);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&p->port);
 
        udma_writel(priv, REGS_DMA_TX, UDMA_TX_TRANSFER_LEN, tx_size);
@@ -540,7 +538,7 @@ static void brcmuart_tx_isr(struct uart_port *up, u32 isr)
        struct brcmuart_priv *priv = up->private_data;
        struct device *dev = up->dev;
        struct uart_8250_port *port_8250 = up_to_u8250p(up);
-       struct circ_buf *xmit = &port_8250->port.state->xmit;
+       struct tty_port *tport = &port_8250->port.state->port;
 
        if (isr & UDMA_INTR_TX_ABORT) {
                if (priv->tx_running)
@@ -548,7 +546,7 @@ static void brcmuart_tx_isr(struct uart_port *up, u32 isr)
                return;
        }
        priv->tx_running = false;
-       if (!uart_circ_empty(xmit) && !uart_tx_stopped(up))
+       if (!kfifo_is_empty(&tport->xmit_fifo) && !uart_tx_stopped(up))
                brcmuart_tx_dma(port_8250);
 }
 
index b62ad9006780ce4b7266ffb0df6066ebecd60ecd..3a1936b7f05fa56e9805983e293e416dd16cdcf3 100644 (file)
@@ -280,7 +280,8 @@ static void serial8250_backup_timeout(struct timer_list *t)
         */
        lsr = serial_lsr_in(up);
        if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
-           (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
+           (!kfifo_is_empty(&up->port.state->port.xmit_fifo) ||
+            up->port.x_char) &&
            (lsr & UART_LSR_THRE)) {
                iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
                iir |= UART_IIR_THRI;
index 8b2c3f478b1782649aa2780e65a768b0902b6e5e..8a353e3cc3dd4223f4aa2f7a3fa73e6786473991 100644 (file)
@@ -15,7 +15,7 @@ static void __dma_tx_complete(void *param)
 {
        struct uart_8250_port   *p = param;
        struct uart_8250_dma    *dma = p->dma;
-       struct circ_buf         *xmit = &p->port.state->xmit;
+       struct tty_port         *tport = &p->port.state->port;
        unsigned long   flags;
        int             ret;
 
@@ -28,7 +28,7 @@ static void __dma_tx_complete(void *param)
 
        uart_xmit_advance(&p->port, dma->tx_size);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&p->port);
 
        ret = serial8250_tx_dma(p);
@@ -86,7 +86,7 @@ static void dma_rx_complete(void *param)
 int serial8250_tx_dma(struct uart_8250_port *p)
 {
        struct uart_8250_dma            *dma = p->dma;
-       struct circ_buf                 *xmit = &p->port.state->xmit;
+       struct tty_port                 *tport = &p->port.state->port;
        struct dma_async_tx_descriptor  *desc;
        struct uart_port                *up = &p->port;
        struct scatterlist sg;
@@ -103,18 +103,23 @@ int serial8250_tx_dma(struct uart_8250_port *p)
                uart_xchar_out(up, UART_TX);
        }
 
-       if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) {
+       if (uart_tx_stopped(&p->port) || kfifo_is_empty(&tport->xmit_fifo)) {
                /* We have been called from __dma_tx_complete() */
                return 0;
        }
 
-       dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
-
        serial8250_do_prepare_tx_dma(p);
 
        sg_init_table(&sg, 1);
-       sg_dma_address(&sg) = dma->tx_addr + xmit->tail;
-       sg_dma_len(&sg) = dma->tx_size;
+       /* kfifo can do more than one sg, we don't (quite yet) */
+       ret = kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, &sg, 1,
+                                          UART_XMIT_SIZE, dma->tx_addr);
+
+       /* we already checked empty fifo above, so there should be something */
+       if (WARN_ON_ONCE(ret != 1))
+               return 0;
+
+       dma->tx_size = sg_dma_len(&sg);
 
        desc = dmaengine_prep_slave_sg(dma->txchan, &sg, 1,
                                       DMA_MEM_TO_DEV,
@@ -257,7 +262,7 @@ int serial8250_request_dma(struct uart_8250_port *p)
 
        /* TX buffer */
        dma->tx_addr = dma_map_single(dma->txchan->device->dev,
-                                       p->port.state->xmit.buf,
+                                       p->port.state->port.xmit_buf,
                                        UART_XMIT_SIZE,
                                        DMA_TO_DEVICE);
        if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
index 0440df7de1ed74379e8862adbf965c320cfc5611..f89dabfc0f974652730cdb0048c9946eb07a7957 100644 (file)
@@ -214,7 +214,7 @@ static void exar_shutdown(struct uart_port *port)
 {
        bool tx_complete = false;
        struct uart_8250_port *up = up_to_u8250p(port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        int i = 0;
        u16 lsr;
 
@@ -225,7 +225,8 @@ static void exar_shutdown(struct uart_port *port)
                else
                        tx_complete = false;
                usleep_range(1000, 1100);
-       } while (!uart_circ_empty(xmit) && !tx_complete && i++ < 1000);
+       } while (!kfifo_is_empty(&tport->xmit_fifo) &&
+                       !tx_complete && i++ < 1000);
 
        serial8250_do_shutdown(port);
 }
index 9ff6bbe9c0863e4c5891f862ea5425b08d813c6b..c365a349421a4a8c2d4d2a835221de1c47c03d0f 100644 (file)
@@ -199,7 +199,7 @@ static int mtk8250_startup(struct uart_port *port)
 
        if (up->dma) {
                data->rx_status = DMA_RX_START;
-               uart_circ_clear(&port->state->xmit);
+               kfifo_reset(&port->state->port.xmit_fifo);
        }
 #endif
        memset(&port->icount, 0, sizeof(port->icount));
index 879e77b307014ff51368902c9124cc8cc55366f2..c07d924d5add35b3c29127a2eb25efa6363b20b5 100644 (file)
@@ -1094,7 +1094,7 @@ static void omap_8250_dma_tx_complete(void *param)
 {
        struct uart_8250_port   *p = param;
        struct uart_8250_dma    *dma = p->dma;
-       struct circ_buf         *xmit = &p->port.state->xmit;
+       struct tty_port         *tport = &p->port.state->port;
        unsigned long           flags;
        bool                    en_thri = false;
        struct omap8250_priv    *priv = p->port.private_data;
@@ -1113,10 +1113,10 @@ static void omap_8250_dma_tx_complete(void *param)
                omap8250_restore_regs(p);
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&p->port);
 
-       if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) {
+       if (!kfifo_is_empty(&tport->xmit_fifo) && !uart_tx_stopped(&p->port)) {
                int ret;
 
                ret = omap_8250_tx_dma(p);
@@ -1138,15 +1138,15 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
 {
        struct uart_8250_dma            *dma = p->dma;
        struct omap8250_priv            *priv = p->port.private_data;
-       struct circ_buf                 *xmit = &p->port.state->xmit;
+       struct tty_port                 *tport = &p->port.state->port;
        struct dma_async_tx_descriptor  *desc;
        struct scatterlist sg;
-       unsigned int    skip_byte = 0;
+       int skip_byte = -1;
        int ret;
 
        if (dma->tx_running)
                return 0;
-       if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) {
+       if (uart_tx_stopped(&p->port) || kfifo_is_empty(&tport->xmit_fifo)) {
 
                /*
                 * Even if no data, we need to return an error for the two cases
@@ -1161,8 +1161,18 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
                return 0;
        }
 
-       dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       sg_init_table(&sg, 1);
+       ret = kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, &sg, 1,
+                                          UART_XMIT_SIZE, dma->tx_addr);
+       if (ret != 1) {
+               serial8250_clear_THRI(p);
+               return 0;
+       }
+
+       dma->tx_size = sg_dma_len(&sg);
+
        if (priv->habit & OMAP_DMA_TX_KICK) {
+               unsigned char c;
                u8 tx_lvl;
 
                /*
@@ -1189,13 +1199,16 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
                        ret = -EINVAL;
                        goto err;
                }
-               skip_byte = 1;
+               if (!kfifo_get(&tport->xmit_fifo, &c)) {
+                       ret = -EINVAL;
+                       goto err;
+               }
+               skip_byte = c;
+               /* now we need to recompute due to kfifo_get */
+               kfifo_dma_out_prepare_mapped(&tport->xmit_fifo, &sg, 1,
+                               UART_XMIT_SIZE, dma->tx_addr);
        }
 
-       sg_init_table(&sg, 1);
-       sg_dma_address(&sg) = dma->tx_addr + xmit->tail + skip_byte;
-       sg_dma_len(&sg) = dma->tx_size - skip_byte;
-
        desc = dmaengine_prep_slave_sg(dma->txchan, &sg, 1, DMA_MEM_TO_DEV,
                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc) {
@@ -1218,11 +1231,13 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
                dma->tx_err = 0;
 
        serial8250_clear_THRI(p);
-       if (skip_byte)
-               serial_out(p, UART_TX, xmit->buf[xmit->tail]);
-       return 0;
+       ret = 0;
+       goto out_skip;
 err:
        dma->tx_err = 1;
+out_skip:
+       if (skip_byte >= 0)
+               serial_out(p, UART_TX, skip_byte);
        return ret;
 }
 
@@ -1311,7 +1326,7 @@ static int omap_8250_dma_handle_irq(struct uart_port *port)
        serial8250_modem_status(up);
        if (status & UART_LSR_THRE && up->dma->tx_err) {
                if (uart_tx_stopped(&up->port) ||
-                   uart_circ_empty(&up->port.state->xmit)) {
+                   kfifo_is_empty(&up->port.state->port.xmit_fifo)) {
                        up->dma->tx_err = 0;
                        serial8250_tx_chars(up);
                } else  {
index 2fbb5851f788b7a45f1002f4d276b4968b067f0e..d3930bf32fe4c4caf6ec8e16dc3628df498250e2 100644 (file)
@@ -382,10 +382,10 @@ static void pci1xxxx_rx_burst(struct uart_port *port, u32 uart_status)
 }
 
 static void pci1xxxx_process_write_data(struct uart_port *port,
-                                       struct circ_buf *xmit,
                                        int *data_empty_count,
                                        u32 *valid_byte_count)
 {
+       struct tty_port *tport = &port->state->port;
        u32 valid_burst_count = *valid_byte_count / UART_BURST_SIZE;
 
        /*
@@ -395,41 +395,36 @@ static void pci1xxxx_process_write_data(struct uart_port *port,
         * one byte at a time.
         */
        while (valid_burst_count) {
+               u32 c;
+
                if (*data_empty_count - UART_BURST_SIZE < 0)
                        break;
-               if (xmit->tail > (UART_XMIT_SIZE - UART_BURST_SIZE))
+               if (kfifo_len(&tport->xmit_fifo) < UART_BURST_SIZE)
+                       break;
+               if (WARN_ON(kfifo_out(&tport->xmit_fifo, (u8 *)&c, sizeof(c)) !=
+                   sizeof(c)))
                        break;
-               writel(*(unsigned int *)&xmit->buf[xmit->tail],
-                      port->membase + UART_TX_BURST_FIFO);
+               writel(c, port->membase + UART_TX_BURST_FIFO);
                *valid_byte_count -= UART_BURST_SIZE;
                *data_empty_count -= UART_BURST_SIZE;
                valid_burst_count -= UART_BYTE_SIZE;
-
-               xmit->tail = (xmit->tail + UART_BURST_SIZE) &
-                            (UART_XMIT_SIZE - 1);
        }
 
        while (*valid_byte_count) {
-               if (*data_empty_count - UART_BYTE_SIZE < 0)
+               u8 c;
+
+               if (!kfifo_get(&tport->xmit_fifo, &c))
                        break;
-               writeb(xmit->buf[xmit->tail], port->membase +
-                      UART_TX_BYTE_FIFO);
+               writeb(c, port->membase + UART_TX_BYTE_FIFO);
                *data_empty_count -= UART_BYTE_SIZE;
                *valid_byte_count -= UART_BYTE_SIZE;
 
-               /*
-                * When the tail of the circular buffer is reached, the next
-                * byte is transferred to the beginning of the buffer.
-                */
-               xmit->tail = (xmit->tail + UART_BYTE_SIZE) &
-                            (UART_XMIT_SIZE - 1);
-
                /*
                 * If there are any pending burst count, data is handled by
                 * transmitting DWORDs at a time.
                 */
-               if (valid_burst_count && (xmit->tail <
-                  (UART_XMIT_SIZE - UART_BURST_SIZE)))
+               if (valid_burst_count &&
+                   kfifo_len(&tport->xmit_fifo) >= UART_BURST_SIZE)
                        break;
        }
 }
@@ -437,11 +432,9 @@ static void pci1xxxx_process_write_data(struct uart_port *port,
 static void pci1xxxx_tx_burst(struct uart_port *port, u32 uart_status)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
+       struct tty_port *tport = &port->state->port;
        u32 valid_byte_count;
        int data_empty_count;
-       struct circ_buf *xmit;
-
-       xmit = &port->state->xmit;
 
        if (port->x_char) {
                writeb(port->x_char, port->membase + UART_TX);
@@ -450,25 +443,25 @@ static void pci1xxxx_tx_burst(struct uart_port *port, u32 uart_status)
                return;
        }
 
-       if ((uart_tx_stopped(port)) || (uart_circ_empty(xmit))) {
+       if ((uart_tx_stopped(port)) || kfifo_is_empty(&tport->xmit_fifo)) {
                port->ops->stop_tx(port);
        } else {
                data_empty_count = (pci1xxxx_read_burst_status(port) &
                                    UART_BST_STAT_TX_COUNT_MASK) >> 8;
                do {
-                       valid_byte_count = uart_circ_chars_pending(xmit);
+                       valid_byte_count = kfifo_len(&tport->xmit_fifo);
 
-                       pci1xxxx_process_write_data(port, xmit,
+                       pci1xxxx_process_write_data(port,
                                                    &data_empty_count,
                                                    &valid_byte_count);
 
                        port->icount.tx++;
-                       if (uart_circ_empty(xmit))
+                       if (kfifo_is_empty(&tport->xmit_fifo))
                                break;
                } while (data_empty_count && valid_byte_count);
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
         /*
@@ -476,7 +469,8 @@ static void pci1xxxx_tx_burst(struct uart_port *port, u32 uart_status)
          * the HW can go idle. So we get here once again with empty FIFO and
          * disable the interrupt and RPM in __stop_tx()
          */
-       if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM))
+       if (kfifo_is_empty(&tport->xmit_fifo) &&
+           !(up->capabilities & UART_CAP_RPM))
                port->ops->stop_tx(port);
 }
 
index fc9dd5d45295da2a526688d442876d5b2c2e18c1..0c19451d0332f56c92d1b14d95de0d811057e944 100644 (file)
@@ -1630,7 +1630,7 @@ static void serial8250_start_tx(struct uart_port *port)
        /* Port locked to synchronize UART_IER access against the console. */
        lockdep_assert_held_once(&port->lock);
 
-       if (!port->x_char && uart_circ_empty(&port->state->xmit))
+       if (!port->x_char && kfifo_is_empty(&port->state->port.xmit_fifo))
                return;
 
        serial8250_rpm_get_tx(up);
@@ -1778,7 +1778,7 @@ EXPORT_SYMBOL_GPL(serial8250_rx_chars);
 void serial8250_tx_chars(struct uart_8250_port *up)
 {
        struct uart_port *port = &up->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        int count;
 
        if (port->x_char) {
@@ -1789,14 +1789,19 @@ void serial8250_tx_chars(struct uart_8250_port *up)
                serial8250_stop_tx(port);
                return;
        }
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                __stop_tx(up);
                return;
        }
 
        count = up->tx_loadsz;
        do {
-               serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+               unsigned char c;
+
+               if (!uart_fifo_get(port, &c))
+                       break;
+
+               serial_out(up, UART_TX, c);
                if (up->bugs & UART_BUG_TXRACE) {
                        /*
                         * The Aspeed BMC virtual UARTs have a bug where data
@@ -1809,9 +1814,7 @@ void serial8250_tx_chars(struct uart_8250_port *up)
                         */
                        serial_in(up, UART_SCR);
                }
-               uart_xmit_advance(port, 1);
-               if (uart_circ_empty(xmit))
-                       break;
+
                if ((up->capabilities & UART_CAP_HFIFO) &&
                    !uart_lsr_tx_empty(serial_in(up, UART_LSR)))
                        break;
@@ -1821,7 +1824,7 @@ void serial8250_tx_chars(struct uart_8250_port *up)
                        break;
        } while (--count > 0);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        /*
@@ -1829,7 +1832,8 @@ void serial8250_tx_chars(struct uart_8250_port *up)
         * HW can go idle. So we get here once again with empty FIFO and disable
         * the interrupt and RPM in __stop_tx()
         */
-       if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM))
+       if (kfifo_is_empty(&tport->xmit_fifo) &&
+           !(up->capabilities & UART_CAP_RPM))
                __stop_tx(up);
 }
 EXPORT_SYMBOL_GPL(serial8250_tx_chars);
index 2fa3fb30dc6c7552667ea68691b28115569c303e..51b202eb8296ffcb97e5496d2a6cfed342f3655d 100644 (file)
@@ -535,6 +535,7 @@ static void pl011_start_tx_pio(struct uart_amba_port *uap);
 static void pl011_dma_tx_callback(void *data)
 {
        struct uart_amba_port *uap = data;
+       struct tty_port *tport = &uap->port.state->port;
        struct pl011_dmatx_data *dmatx = &uap->dmatx;
        unsigned long flags;
        u16 dmacr;
@@ -558,7 +559,7 @@ static void pl011_dma_tx_callback(void *data)
         * get further refills (hence we check dmacr).
         */
        if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) ||
-           uart_circ_empty(&uap->port.state->xmit)) {
+           kfifo_is_empty(&tport->xmit_fifo)) {
                uap->dmatx.queued = false;
                uart_port_unlock_irqrestore(&uap->port, flags);
                return;
@@ -588,7 +589,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap)
        struct dma_chan *chan = dmatx->chan;
        struct dma_device *dma_dev = chan->device;
        struct dma_async_tx_descriptor *desc;
-       struct circ_buf *xmit = &uap->port.state->xmit;
+       struct tty_port *tport = &uap->port.state->port;
        unsigned int count;
 
        /*
@@ -597,7 +598,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap)
         * the standard interrupt handling.  This ensures that we
         * issue a uart_write_wakeup() at the appropriate time.
         */
-       count = uart_circ_chars_pending(xmit);
+       count = kfifo_len(&tport->xmit_fifo);
        if (count < (uap->fifosize >> 1)) {
                uap->dmatx.queued = false;
                return 0;
@@ -613,21 +614,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap)
        if (count > PL011_DMA_BUFFER_SIZE)
                count = PL011_DMA_BUFFER_SIZE;
 
-       if (xmit->tail < xmit->head) {
-               memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], count);
-       } else {
-               size_t first = UART_XMIT_SIZE - xmit->tail;
-               size_t second;
-
-               if (first > count)
-                       first = count;
-               second = count - first;
-
-               memcpy(&dmatx->buf[0], &xmit->buf[xmit->tail], first);
-               if (second)
-                       memcpy(&dmatx->buf[first], &xmit->buf[0], second);
-       }
-
+       count = kfifo_out_peek(&tport->xmit_fifo, dmatx->buf, count);
        dmatx->len = count;
        dmatx->dma = dma_map_single(dma_dev->dev, dmatx->buf, count,
                                    DMA_TO_DEVICE);
@@ -670,7 +657,7 @@ static int pl011_dma_tx_refill(struct uart_amba_port *uap)
         */
        uart_xmit_advance(&uap->port, count);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&uap->port);
 
        return 1;
@@ -1454,7 +1441,7 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
 /* Returns true if tx interrupts have to be (kept) enabled  */
 static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
 {
-       struct circ_buf *xmit = &uap->port.state->xmit;
+       struct tty_port *tport = &uap->port.state->port;
        int count = uap->fifosize >> 1;
 
        if (uap->port.x_char) {
@@ -1463,7 +1450,7 @@ static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
                uap->port.x_char = 0;
                --count;
        }
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(&uap->port)) {
                pl011_stop_tx(&uap->port);
                return false;
        }
@@ -1472,20 +1459,25 @@ static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq)
        if (pl011_dma_tx_irq(uap))
                return true;
 
-       do {
+       while (1) {
+               unsigned char c;
+
                if (likely(from_irq) && count-- == 0)
                        break;
 
-               if (!pl011_tx_char(uap, xmit->buf[xmit->tail], from_irq))
+               if (!kfifo_peek(&tport->xmit_fifo, &c))
+                       break;
+
+               if (!pl011_tx_char(uap, c, from_irq))
                        break;
 
-               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-       } while (!uart_circ_empty(xmit));
+               kfifo_skip(&tport->xmit_fifo);
+       }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&uap->port);
 
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                pl011_stop_tx(&uap->port);
                return false;
        }
index 7790cbc57391aaafedc70a33cc24fd1f5da5d54d..f2836ecc5c19e55af242bc2135212d0547337412 100644 (file)
@@ -390,7 +390,7 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
 
 static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
 {
-       struct circ_buf *xmit = &up->port.state->xmit;
+       struct tty_port *tport = &up->port.state->port;
        struct serial_rs485 *rs485conf = &up->port.rs485;
        int count;
        bool half_duplex_send = false;
@@ -399,7 +399,7 @@ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
                return;
 
        if ((rs485conf->flags & SER_RS485_ENABLED) &&
-           (up->port.x_char || !uart_circ_empty(xmit))) {
+           (up->port.x_char || !kfifo_is_empty(&tport->xmit_fifo))) {
                ar933x_uart_stop_rx_interrupt(up);
                gpiod_set_value(up->rts_gpiod, !!(rs485conf->flags & SER_RS485_RTS_ON_SEND));
                half_duplex_send = true;
@@ -408,6 +408,7 @@ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
        count = up->port.fifosize;
        do {
                unsigned int rdata;
+               unsigned char c;
 
                rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
                if ((rdata & AR933X_UART_DATA_TX_CSR) == 0)
@@ -420,18 +421,16 @@ static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
                        continue;
                }
 
-               if (uart_circ_empty(xmit))
+               if (!uart_fifo_get(&up->port, &c))
                        break;
 
-               ar933x_uart_putc(up, xmit->buf[xmit->tail]);
-
-               uart_xmit_advance(&up->port, 1);
+               ar933x_uart_putc(up, c);
        } while (--count > 0);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&up->port);
 
-       if (!uart_circ_empty(xmit)) {
+       if (!kfifo_is_empty(&tport->xmit_fifo)) {
                ar933x_uart_start_tx_interrupt(up);
        } else if (half_duplex_send) {
                ar933x_uart_wait_tx_complete(up);
index 1aa5b2b49c265d4c71e634d57df25456077906dc..5c4895d154c00ef6f2382739b0afe34494121a65 100644 (file)
@@ -155,7 +155,7 @@ static unsigned int arc_serial_tx_empty(struct uart_port *port)
  */
 static void arc_serial_tx_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        int sent = 0;
        unsigned char ch;
 
@@ -164,9 +164,7 @@ static void arc_serial_tx_chars(struct uart_port *port)
                port->icount.tx++;
                port->x_char = 0;
                sent = 1;
-       } else if (!uart_circ_empty(xmit)) {
-               ch = xmit->buf[xmit->tail];
-               uart_xmit_advance(port, 1);
+       } else if (uart_fifo_get(port, &ch)) {
                while (!(UART_GET_STATUS(port) & TXEMPTY))
                        cpu_relax();
                UART_SET_DATA(port, ch);
@@ -177,7 +175,7 @@ static void arc_serial_tx_chars(struct uart_port *port)
         * If num chars in xmit buffer are too few, ask tty layer for more.
         * By Hard ISR to schedule processing in software interrupt part
         */
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        if (sent)
index 85667f7095154eff29a7ba402f99894518d78c60..5bb5e4303754bfd25bcb0728c21911a7c549f978 100644 (file)
@@ -857,7 +857,7 @@ static void atmel_complete_tx_dma(void *arg)
 {
        struct atmel_uart_port *atmel_port = arg;
        struct uart_port *port = &atmel_port->uart;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct dma_chan *chan = atmel_port->chan_tx;
        unsigned long flags;
 
@@ -873,15 +873,15 @@ static void atmel_complete_tx_dma(void *arg)
        atmel_port->desc_tx = NULL;
        spin_unlock(&atmel_port->lock_tx);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        /*
-        * xmit is a circular buffer so, if we have just send data from
-        * xmit->tail to the end of xmit->buf, now we have to transmit the
-        * remaining data from the beginning of xmit->buf to xmit->head.
+        * xmit is a circular buffer so, if we have just send data from the
+        * tail to the end, now we have to transmit the remaining data from the
+        * beginning to the head.
         */
-       if (!uart_circ_empty(xmit))
+       if (!kfifo_is_empty(&tport->xmit_fifo))
                atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
        else if (atmel_uart_is_half_duplex(port)) {
                /*
@@ -919,18 +919,18 @@ static void atmel_release_tx_dma(struct uart_port *port)
 static void atmel_tx_dma(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct dma_chan *chan = atmel_port->chan_tx;
        struct dma_async_tx_descriptor *desc;
        struct scatterlist sgl[2], *sg, *sg_tx = &atmel_port->sg_tx;
-       unsigned int tx_len, part1_len, part2_len, sg_len;
+       unsigned int tx_len, tail, part1_len, part2_len, sg_len;
        dma_addr_t phys_addr;
 
        /* Make sure we have an idle channel */
        if (atmel_port->desc_tx != NULL)
                return;
 
-       if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) {
+       if (!kfifo_is_empty(&tport->xmit_fifo) && !uart_tx_stopped(port)) {
                /*
                 * DMA is idle now.
                 * Port xmit buffer is already mapped,
@@ -940,9 +940,8 @@ static void atmel_tx_dma(struct uart_port *port)
                 * Take the port lock to get a
                 * consistent xmit buffer state.
                 */
-               tx_len = CIRC_CNT_TO_END(xmit->head,
-                                        xmit->tail,
-                                        UART_XMIT_SIZE);
+               tx_len = kfifo_out_linear(&tport->xmit_fifo, &tail,
+                               UART_XMIT_SIZE);
 
                if (atmel_port->fifo_size) {
                        /* multi data mode */
@@ -956,7 +955,7 @@ static void atmel_tx_dma(struct uart_port *port)
 
                sg_init_table(sgl, 2);
                sg_len = 0;
-               phys_addr = sg_dma_address(sg_tx) + xmit->tail;
+               phys_addr = sg_dma_address(sg_tx) + tail;
                if (part1_len) {
                        sg = &sgl[sg_len++];
                        sg_dma_address(sg) = phys_addr;
@@ -973,7 +972,7 @@ static void atmel_tx_dma(struct uart_port *port)
 
                /*
                 * save tx_len so atmel_complete_tx_dma() will increase
-                * xmit->tail correctly
+                * tail correctly
                 */
                atmel_port->tx_len = tx_len;
 
@@ -1003,13 +1002,14 @@ static void atmel_tx_dma(struct uart_port *port)
                dma_async_issue_pending(chan);
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 }
 
 static int atmel_prepare_tx_dma(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+       struct tty_port *tport = &port->state->port;
        struct device *mfd_dev = port->dev->parent;
        dma_cap_mask_t          mask;
        struct dma_slave_config config;
@@ -1031,11 +1031,11 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
        spin_lock_init(&atmel_port->lock_tx);
        sg_init_table(&atmel_port->sg_tx, 1);
        /* UART circular tx buffer is an aligned page. */
-       BUG_ON(!PAGE_ALIGNED(port->state->xmit.buf));
+       BUG_ON(!PAGE_ALIGNED(tport->xmit_buf));
        sg_set_page(&atmel_port->sg_tx,
-                       virt_to_page(port->state->xmit.buf),
+                       virt_to_page(tport->xmit_buf),
                        UART_XMIT_SIZE,
-                       offset_in_page(port->state->xmit.buf));
+                       offset_in_page(tport->xmit_buf));
        nent = dma_map_sg(port->dev,
                                &atmel_port->sg_tx,
                                1,
@@ -1047,7 +1047,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port)
        } else {
                dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n", __func__,
                        sg_dma_len(&atmel_port->sg_tx),
-                       port->state->xmit.buf,
+                       tport->xmit_buf,
                        &sg_dma_address(&atmel_port->sg_tx));
        }
 
@@ -1459,9 +1459,8 @@ static void atmel_release_tx_pdc(struct uart_port *port)
 static void atmel_tx_pdc(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
-       int count;
 
        /* nothing left to transmit? */
        if (atmel_uart_readl(port, ATMEL_PDC_TCR))
@@ -1474,17 +1473,19 @@ static void atmel_tx_pdc(struct uart_port *port)
        /* disable PDC transmit */
        atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS);
 
-       if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) {
+       if (!kfifo_is_empty(&tport->xmit_fifo) && !uart_tx_stopped(port)) {
+               unsigned int count, tail;
+
                dma_sync_single_for_device(port->dev,
                                           pdc->dma_addr,
                                           pdc->dma_size,
                                           DMA_TO_DEVICE);
 
-               count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+               count = kfifo_out_linear(&tport->xmit_fifo, &tail,
+                               UART_XMIT_SIZE);
                pdc->ofs = count;
 
-               atmel_uart_writel(port, ATMEL_PDC_TPR,
-                                 pdc->dma_addr + xmit->tail);
+               atmel_uart_writel(port, ATMEL_PDC_TPR, pdc->dma_addr + tail);
                atmel_uart_writel(port, ATMEL_PDC_TCR, count);
                /* re-enable PDC transmit */
                atmel_uart_writel(port, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
@@ -1498,7 +1499,7 @@ static void atmel_tx_pdc(struct uart_port *port)
                }
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 }
 
@@ -1506,9 +1507,9 @@ static int atmel_prepare_tx_pdc(struct uart_port *port)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
        struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
-       pdc->buf = xmit->buf;
+       pdc->buf = tport->xmit_buf;
        pdc->dma_addr = dma_map_single(port->dev,
                                        pdc->buf,
                                        UART_XMIT_SIZE,
index 7927725b8957809d4bfea0f1446d9faba9762bdd..30425a3d19fbe04e3b544a5bdb2b3a216fd84ad2 100644 (file)
@@ -146,7 +146,8 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id)
 {
        struct uart_port *port = dev_id;
        struct clps711x_port *s = dev_get_drvdata(port->dev);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
+       unsigned char c;
 
        if (port->x_char) {
                writew(port->x_char, port->membase + UARTDR_OFFSET);
@@ -155,7 +156,7 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id)
                return IRQ_HANDLED;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                if (s->tx_enabled) {
                        disable_irq_nosync(port->irq);
                        s->tx_enabled = 0;
@@ -163,18 +164,17 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id)
                return IRQ_HANDLED;
        }
 
-       while (!uart_circ_empty(xmit)) {
+       while (uart_fifo_get(port, &c)) {
                u32 sysflg = 0;
 
-               writew(xmit->buf[xmit->tail], port->membase + UARTDR_OFFSET);
-               uart_xmit_advance(port, 1);
+               writew(c, port->membase + UARTDR_OFFSET);
 
                regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
                if (sysflg & SYSFLG_UTXFF)
                        break;
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        return IRQ_HANDLED;
index df56c6c5afd0e50bbc595f56cf3c24313654e98e..a927478f581d71431a8d035bd3758af654a10bba 100644 (file)
@@ -648,7 +648,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
        int count;
        struct uart_cpm_port *pinfo =
                container_of(port, struct uart_cpm_port, port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
        /* Handle xon/xoff */
        if (port->x_char) {
@@ -673,7 +673,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
                return 1;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                cpm_uart_stop_tx(port);
                return 0;
        }
@@ -681,16 +681,10 @@ static int cpm_uart_tx_pump(struct uart_port *port)
        /* Pick next descriptor and fill from buffer */
        bdp = pinfo->tx_cur;
 
-       while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && !uart_circ_empty(xmit)) {
-               count = 0;
+       while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) &&
+                       !kfifo_is_empty(&tport->xmit_fifo)) {
                p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
-               while (count < pinfo->tx_fifosize) {
-                       *p++ = xmit->buf[xmit->tail];
-                       uart_xmit_advance(port, 1);
-                       count++;
-                       if (uart_circ_empty(xmit))
-                               break;
-               }
+               count = uart_fifo_out(port, p, pinfo->tx_fifosize);
                out_be16(&bdp->cbd_datlen, count);
                setbits16(&bdp->cbd_sc, BD_SC_READY);
                /* Get next BD. */
@@ -701,10 +695,10 @@ static int cpm_uart_tx_pump(struct uart_port *port)
        }
        pinfo->tx_cur = bdp;
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                cpm_uart_stop_tx(port);
                return 0;
        }
index e419c4bde8b787d7f6ca399c9067da2482d39347..2ccd13cc0a899f589bd5b80cc70081c3d053ff62 100644 (file)
@@ -179,8 +179,9 @@ static void digicolor_uart_rx(struct uart_port *port)
 
 static void digicolor_uart_tx(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        unsigned long flags;
+       unsigned char c;
 
        if (digicolor_uart_tx_full(port))
                return;
@@ -194,20 +195,19 @@ static void digicolor_uart_tx(struct uart_port *port)
                goto out;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                digicolor_uart_stop_tx(port);
                goto out;
        }
 
-       while (!uart_circ_empty(xmit)) {
-               writeb(xmit->buf[xmit->tail], port->membase + UA_EMI_REC);
-               uart_xmit_advance(port, 1);
+       while (uart_fifo_get(port, &c)) {
+               writeb(c, port->membase + UA_EMI_REC);
 
                if (digicolor_uart_tx_full(port))
                        break;
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
 out:
index 6df7af9edc1cdc80fc5fb7877ef338e1f3a729c2..eba91daedef814c86e54edaf641602a677a24f0b 100644 (file)
@@ -252,13 +252,13 @@ static inline void dz_receive_chars(struct dz_mux *mux)
 static inline void dz_transmit_chars(struct dz_mux *mux)
 {
        struct dz_port *dport = &mux->dport[0];
-       struct circ_buf *xmit;
+       struct tty_port *tport;
        unsigned char tmp;
        u16 status;
 
        status = dz_in(dport, DZ_CSR);
        dport = &mux->dport[LINE(status)];
-       xmit = &dport->port.state->xmit;
+       tport = &dport->port.state->port;
 
        if (dport->port.x_char) {               /* XON/XOFF chars */
                dz_out(dport, DZ_TDR, dport->port.x_char);
@@ -267,7 +267,8 @@ static inline void dz_transmit_chars(struct dz_mux *mux)
                return;
        }
        /* If nothing to do or stopped or hardware stopped. */
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
+       if (uart_tx_stopped(&dport->port) ||
+                       !uart_fifo_get(&dport->port, &tmp)) {
                uart_port_lock(&dport->port);
                dz_stop_tx(&dport->port);
                uart_port_unlock(&dport->port);
@@ -278,15 +279,13 @@ static inline void dz_transmit_chars(struct dz_mux *mux)
         * If something to do... (remember the dz has no output fifo,
         * so we go one char at a time) :-<
         */
-       tmp = xmit->buf[xmit->tail];
        dz_out(dport, DZ_TDR, tmp);
-       uart_xmit_advance(&dport->port, 1);
 
-       if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < DZ_WAKEUP_CHARS)
                uart_write_wakeup(&dport->port);
 
        /* Are we are done. */
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                uart_port_lock(&dport->port);
                dz_stop_tx(&dport->port);
                uart_port_unlock(&dport->port);
index 5426322b5f0ca3f8580880bd9bb86131e676b573..e972df4b188d3b061606f42cbbeb9cdc1ec36ca9 100644 (file)
@@ -174,17 +174,18 @@ static void linflex_put_char(struct uart_port *sport, unsigned char c)
 
 static inline void linflex_transmit_buffer(struct uart_port *sport)
 {
-       struct circ_buf *xmit = &sport->state->xmit;
+       struct tty_port *tport = &sport->state->port;
+       unsigned char c;
 
-       while (!uart_circ_empty(xmit)) {
-               linflex_put_char(sport, xmit->buf[xmit->tail]);
-               uart_xmit_advance(sport, 1);
+       while (uart_fifo_get(sport, &c)) {
+               linflex_put_char(sport, c);
+               sport->icount.tx++;
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(sport);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                linflex_stop_tx(sport);
 }
 
@@ -200,7 +201,7 @@ static void linflex_start_tx(struct uart_port *port)
 static irqreturn_t linflex_txint(int irq, void *dev_id)
 {
        struct uart_port *sport = dev_id;
-       struct circ_buf *xmit = &sport->state->xmit;
+       struct tty_port *tport = &sport->state->port;
        unsigned long flags;
 
        uart_port_lock_irqsave(sport, &flags);
@@ -210,7 +211,7 @@ static irqreturn_t linflex_txint(int irq, void *dev_id)
                goto out;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(sport)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(sport)) {
                linflex_stop_tx(sport);
                goto out;
        }
index bbcbc91482af0bbd04db16242b4d955d21a9753a..ae5e1ecc48fc692a2e27e65aea9f488d776e2a9d 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/bits.h>
+#include <linux/circ_buf.h>
 #include <linux/clk.h>
 #include <linux/console.h>
 #include <linux/delay.h>
@@ -473,7 +474,7 @@ static void lpuart32_stop_rx(struct uart_port *port)
 
 static void lpuart_dma_tx(struct lpuart_port *sport)
 {
-       struct circ_buf *xmit = &sport->port.state->xmit;
+       struct tty_port *tport = &sport->port.state->port;
        struct scatterlist *sgl = sport->tx_sgl;
        struct device *dev = sport->port.dev;
        struct dma_chan *chan = sport->dma_tx_chan;
@@ -482,18 +483,10 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
        if (sport->dma_tx_in_progress)
                return;
 
-       sport->dma_tx_bytes = uart_circ_chars_pending(xmit);
-
-       if (xmit->tail < xmit->head || xmit->head == 0) {
-               sport->dma_tx_nents = 1;
-               sg_init_one(sgl, xmit->buf + xmit->tail, sport->dma_tx_bytes);
-       } else {
-               sport->dma_tx_nents = 2;
-               sg_init_table(sgl, 2);
-               sg_set_buf(sgl, xmit->buf + xmit->tail,
-                               UART_XMIT_SIZE - xmit->tail);
-               sg_set_buf(sgl + 1, xmit->buf, xmit->head);
-       }
+       sg_init_table(sgl, ARRAY_SIZE(sport->tx_sgl));
+       sport->dma_tx_bytes = kfifo_len(&tport->xmit_fifo);
+       sport->dma_tx_nents = kfifo_dma_out_prepare(&tport->xmit_fifo, sgl,
+                       ARRAY_SIZE(sport->tx_sgl), sport->dma_tx_bytes);
 
        ret = dma_map_sg(chan->device->dev, sgl, sport->dma_tx_nents,
                         DMA_TO_DEVICE);
@@ -521,14 +514,15 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
 
 static bool lpuart_stopped_or_empty(struct uart_port *port)
 {
-       return uart_circ_empty(&port->state->xmit) || uart_tx_stopped(port);
+       return kfifo_is_empty(&port->state->port.xmit_fifo) ||
+               uart_tx_stopped(port);
 }
 
 static void lpuart_dma_tx_complete(void *arg)
 {
        struct lpuart_port *sport = arg;
        struct scatterlist *sgl = &sport->tx_sgl[0];
-       struct circ_buf *xmit = &sport->port.state->xmit;
+       struct tty_port *tport = &sport->port.state->port;
        struct dma_chan *chan = sport->dma_tx_chan;
        unsigned long flags;
 
@@ -545,7 +539,7 @@ static void lpuart_dma_tx_complete(void *arg)
        sport->dma_tx_in_progress = false;
        uart_port_unlock_irqrestore(&sport->port, flags);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&sport->port);
 
        if (waitqueue_active(&sport->dma_wait)) {
@@ -756,8 +750,9 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
 
 static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
 {
-       struct circ_buf *xmit = &sport->port.state->xmit;
+       struct tty_port *tport = &sport->port.state->port;
        unsigned long txcnt;
+       unsigned char c;
 
        if (sport->port.x_char) {
                lpuart32_write(&sport->port, sport->port.x_char, UARTDATA);
@@ -774,18 +769,18 @@ static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
        txcnt = lpuart32_read(&sport->port, UARTWATER);
        txcnt = txcnt >> UARTWATER_TXCNT_OFF;
        txcnt &= UARTWATER_COUNT_MASK;
-       while (!uart_circ_empty(xmit) && (txcnt < sport->txfifo_size)) {
-               lpuart32_write(&sport->port, xmit->buf[xmit->tail], UARTDATA);
-               uart_xmit_advance(&sport->port, 1);
+       while (txcnt < sport->txfifo_size &&
+                       uart_fifo_get(&sport->port, &c)) {
+               lpuart32_write(&sport->port, c, UARTDATA);
                txcnt = lpuart32_read(&sport->port, UARTWATER);
                txcnt = txcnt >> UARTWATER_TXCNT_OFF;
                txcnt &= UARTWATER_COUNT_MASK;
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&sport->port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                lpuart32_stop_tx(&sport->port);
 }
 
index a75eafbcbea38495da49f44d5e015c594c52ba11..29e42831df39c02501d682e8f3e7e429b1080268 100644 (file)
@@ -877,10 +877,10 @@ unlock:
 static int icom_write(struct uart_port *port)
 {
        struct icom_port *icom_port = to_icom_port(port);
+       struct tty_port *tport = &port->state->port;
        unsigned long data_count;
        unsigned char cmdReg;
        unsigned long offset;
-       int temp_tail = port->state->xmit.tail;
 
        trace(icom_port, "WRITE", 0);
 
@@ -890,16 +890,8 @@ static int icom_write(struct uart_port *port)
                return 0;
        }
 
-       data_count = 0;
-       while ((port->state->xmit.head != temp_tail) &&
-              (data_count <= XMIT_BUFF_SZ)) {
-
-               icom_port->xmit_buf[data_count++] =
-                   port->state->xmit.buf[temp_tail];
-
-               temp_tail++;
-               temp_tail &= (UART_XMIT_SIZE - 1);
-       }
+       data_count = kfifo_out_peek(&tport->xmit_fifo, icom_port->xmit_buf,
+                       XMIT_BUFF_SZ);
 
        if (data_count) {
                icom_port->statStg->xmit[0].flags =
@@ -956,7 +948,8 @@ static inline void check_modem_status(struct icom_port *icom_port)
 
 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 {
-       u16 count, i;
+       struct tty_port *tport = &icom_port->uart_port.state->port;
+       u16 count;
 
        if (port_int_reg & (INT_XMIT_COMPLETED)) {
                trace(icom_port, "XMIT_COMPLETE", 0);
@@ -968,13 +961,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
                count = le16_to_cpu(icom_port->statStg->xmit[0].leLength);
                icom_port->uart_port.icount.tx += count;
 
-               for (i=0; i<count &&
-                       !uart_circ_empty(&icom_port->uart_port.state->xmit); i++) {
-
-                       icom_port->uart_port.state->xmit.tail++;
-                       icom_port->uart_port.state->xmit.tail &=
-                               (UART_XMIT_SIZE - 1);
-               }
+               kfifo_skip_count(&tport->xmit_fifo, count);
 
                if (!icom_write(&icom_port->uart_port))
                        /* activate write queue */
index e14813250616118e5ecfcfdafc1a4c1033f2bf79..56b76a221082a15d07257c18888da69dd544ed46 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 2004 Pengutronix
  */
 
+#include <linux/circ_buf.h>
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
@@ -521,7 +522,8 @@ static void imx_uart_dma_tx(struct imx_port *sport);
 /* called with port.lock taken and irqs off */
 static inline void imx_uart_transmit_buffer(struct imx_port *sport)
 {
-       struct circ_buf *xmit = &sport->port.state->xmit;
+       struct tty_port *tport = &sport->port.state->port;
+       unsigned char c;
 
        if (sport->port.x_char) {
                /* Send next char */
@@ -531,7 +533,8 @@ static inline void imx_uart_transmit_buffer(struct imx_port *sport)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) ||
+                       uart_tx_stopped(&sport->port)) {
                imx_uart_stop_tx(&sport->port);
                return;
        }
@@ -555,26 +558,22 @@ static inline void imx_uart_transmit_buffer(struct imx_port *sport)
                return;
        }
 
-       while (!uart_circ_empty(xmit) &&
-              !(imx_uart_readl(sport, imx_uart_uts_reg(sport)) & UTS_TXFULL)) {
-               /* send xmit->buf[xmit->tail]
-                * out the port here */
-               imx_uart_writel(sport, xmit->buf[xmit->tail], URTX0);
-               uart_xmit_advance(&sport->port, 1);
-       }
+       while (!(imx_uart_readl(sport, imx_uart_uts_reg(sport)) & UTS_TXFULL) &&
+                       uart_fifo_get(&sport->port, &c))
+               imx_uart_writel(sport, c, URTX0);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&sport->port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                imx_uart_stop_tx(&sport->port);
 }
 
 static void imx_uart_dma_tx_callback(void *data)
 {
        struct imx_port *sport = data;
+       struct tty_port *tport = &sport->port.state->port;
        struct scatterlist *sgl = &sport->tx_sgl[0];
-       struct circ_buf *xmit = &sport->port.state->xmit;
        unsigned long flags;
        u32 ucr1;
 
@@ -592,10 +591,11 @@ static void imx_uart_dma_tx_callback(void *data)
 
        sport->dma_is_txing = 0;
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&sport->port);
 
-       if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port))
+       if (!kfifo_is_empty(&tport->xmit_fifo) &&
+                       !uart_tx_stopped(&sport->port))
                imx_uart_dma_tx(sport);
        else if (sport->port.rs485.flags & SER_RS485_ENABLED) {
                u32 ucr4 = imx_uart_readl(sport, UCR4);
@@ -609,7 +609,7 @@ static void imx_uart_dma_tx_callback(void *data)
 /* called with port.lock taken and irqs off */
 static void imx_uart_dma_tx(struct imx_port *sport)
 {
-       struct circ_buf *xmit = &sport->port.state->xmit;
+       struct tty_port *tport = &sport->port.state->port;
        struct scatterlist *sgl = sport->tx_sgl;
        struct dma_async_tx_descriptor *desc;
        struct dma_chan *chan = sport->dma_chan_tx;
@@ -624,18 +624,10 @@ static void imx_uart_dma_tx(struct imx_port *sport)
        ucr4 &= ~UCR4_TCEN;
        imx_uart_writel(sport, ucr4, UCR4);
 
-       sport->tx_bytes = uart_circ_chars_pending(xmit);
-
-       if (xmit->tail < xmit->head || xmit->head == 0) {
-               sport->dma_tx_nents = 1;
-               sg_init_one(sgl, xmit->buf + xmit->tail, sport->tx_bytes);
-       } else {
-               sport->dma_tx_nents = 2;
-               sg_init_table(sgl, 2);
-               sg_set_buf(sgl, xmit->buf + xmit->tail,
-                               UART_XMIT_SIZE - xmit->tail);
-               sg_set_buf(sgl + 1, xmit->buf, xmit->head);
-       }
+       sg_init_table(sgl, ARRAY_SIZE(sport->tx_sgl));
+       sport->tx_bytes = kfifo_len(&tport->xmit_fifo);
+       sport->dma_tx_nents = kfifo_dma_out_prepare(&tport->xmit_fifo, sgl,
+                       ARRAY_SIZE(sport->tx_sgl), sport->tx_bytes);
 
        ret = dma_map_sg(dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
        if (ret == 0) {
@@ -653,8 +645,7 @@ static void imx_uart_dma_tx(struct imx_port *sport)
        desc->callback = imx_uart_dma_tx_callback;
        desc->callback_param = sport;
 
-       dev_dbg(dev, "TX: prepare to send %lu bytes by DMA.\n",
-                       uart_circ_chars_pending(xmit));
+       dev_dbg(dev, "TX: prepare to send %u bytes by DMA.\n", sport->tx_bytes);
 
        ucr1 = imx_uart_readl(sport, UCR1);
        ucr1 |= UCR1_TXDMAEN;
@@ -671,9 +662,10 @@ static void imx_uart_dma_tx(struct imx_port *sport)
 static void imx_uart_start_tx(struct uart_port *port)
 {
        struct imx_port *sport = (struct imx_port *)port;
+       struct tty_port *tport = &sport->port.state->port;
        u32 ucr1;
 
-       if (!sport->port.x_char && uart_circ_empty(&port->state->xmit))
+       if (!sport->port.x_char && kfifo_is_empty(&tport->xmit_fifo))
                return;
 
        /*
@@ -749,7 +741,7 @@ static void imx_uart_start_tx(struct uart_port *port)
                        return;
                }
 
-               if (!uart_circ_empty(&port->state->xmit) &&
+               if (!kfifo_is_empty(&tport->xmit_fifo) &&
                    !uart_tx_stopped(port))
                        imx_uart_dma_tx(sport);
                return;
index 320b29cd4683bdf55317834eb5fa416ea0f4258f..c2cae50f06f335fbe314f648307e59460f5c1c16 100644 (file)
@@ -355,7 +355,8 @@ static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
 static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
                                    struct zilog_channel *channel)
 {
-       struct circ_buf *xmit;
+       struct tty_port *tport;
+       unsigned char c;
 
        if (ZS_IS_CONS(up)) {
                unsigned char status = readb(&channel->control);
@@ -398,20 +399,18 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
 
        if (up->port.state == NULL)
                goto ack_tx_int;
-       xmit = &up->port.state->xmit;
-       if (uart_circ_empty(xmit))
-               goto ack_tx_int;
+       tport = &up->port.state->port;
        if (uart_tx_stopped(&up->port))
                goto ack_tx_int;
+       if (!uart_fifo_get(&up->port, &c))
+               goto ack_tx_int;
 
        up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
-       writeb(xmit->buf[xmit->tail], &channel->data);
+       writeb(c, &channel->data);
        ZSDELAY();
        ZS_WSYNC(channel);
 
-       uart_xmit_advance(&up->port, 1);
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&up->port);
 
        return;
@@ -600,17 +599,16 @@ static void ip22zilog_start_tx(struct uart_port *port)
                port->icount.tx++;
                port->x_char = 0;
        } else {
-               struct circ_buf *xmit = &port->state->xmit;
+               struct tty_port *tport = &port->state->port;
+               unsigned char c;
 
-               if (uart_circ_empty(xmit))
+               if (!uart_fifo_get(port, &c))
                        return;
-               writeb(xmit->buf[xmit->tail], &channel->data);
+               writeb(c, &channel->data);
                ZSDELAY();
                ZS_WSYNC(channel);
 
-               uart_xmit_advance(port, 1);
-
-               if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                        uart_write_wakeup(&up->port);
        }
 }
index ddbd42c09637cdc9bcc2438367b53e2b4fb8f551..6e40792f92cffdac99aacb4ee488f3059de73b3e 100644 (file)
@@ -443,20 +443,14 @@ static void cls_copy_data_from_uart_to_queue(struct jsm_channel *ch)
 
 static void cls_copy_data_from_queue_to_uart(struct jsm_channel *ch)
 {
-       u16 tail;
+       struct tty_port *tport;
        int n;
-       int qlen;
        u32 len_written = 0;
-       struct circ_buf *circ;
 
        if (!ch)
                return;
 
-       circ = &ch->uart_port.state->xmit;
-
-       /* No data to write to the UART */
-       if (uart_circ_empty(circ))
-               return;
+       tport = &ch->uart_port.state->port;
 
        /* If port is "stopped", don't send any data to the UART */
        if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_BREAK_SENDING))
@@ -467,29 +461,22 @@ static void cls_copy_data_from_queue_to_uart(struct jsm_channel *ch)
                return;
 
        n = 32;
+       while (n > 0) {
+               unsigned char c;
 
-       /* cache tail of queue */
-       tail = circ->tail & (UART_XMIT_SIZE - 1);
-       qlen = uart_circ_chars_pending(circ);
-
-       /* Find minimum of the FIFO space, versus queue length */
-       n = min(n, qlen);
+               if (!kfifo_get(&tport->xmit_fifo, &c))
+                       break;
 
-       while (n > 0) {
-               writeb(circ->buf[tail], &ch->ch_cls_uart->txrx);
-               tail = (tail + 1) & (UART_XMIT_SIZE - 1);
+               writeb(c, &ch->ch_cls_uart->txrx);
                n--;
                ch->ch_txcount++;
                len_written++;
        }
 
-       /* Update the final tail */
-       circ->tail = tail & (UART_XMIT_SIZE - 1);
-
        if (len_written > ch->ch_t_tlevel)
                ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 
-       if (uart_circ_empty(circ))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                uart_write_wakeup(&ch->uart_port);
 }
 
index 1fa10f19368f57edb7b6b097bfc3236541890952..e8e13bf056e205404d00205576d96e3e84b4de18 100644 (file)
@@ -474,21 +474,21 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch)
 
 static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
 {
-       u16 head;
-       u16 tail;
+       struct tty_port *tport;
+       unsigned char *tail;
+       unsigned char c;
        int n;
        int s;
        int qlen;
        u32 len_written = 0;
-       struct circ_buf *circ;
 
        if (!ch)
                return;
 
-       circ = &ch->uart_port.state->xmit;
+       tport = &ch->uart_port.state->port;
 
        /* No data to write to the UART */
-       if (uart_circ_empty(circ))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                return;
 
        /* If port is "stopped", don't send any data to the UART */
@@ -504,10 +504,9 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
                if (ch->ch_cached_lsr & UART_LSR_THRE) {
                        ch->ch_cached_lsr &= ~(UART_LSR_THRE);
 
-                       writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx);
-                       jsm_dbg(WRITE, &ch->ch_bd->pci_dev,
-                               "Tx data: %x\n", circ->buf[circ->tail]);
-                       circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1);
+                       WARN_ON_ONCE(!kfifo_get(&tport->xmit_fifo, &c));
+                       writeb(c, &ch->ch_neo_uart->txrx);
+                       jsm_dbg(WRITE, &ch->ch_bd->pci_dev, "Tx data: %x\n", c);
                        ch->ch_txcount++;
                }
                return;
@@ -520,38 +519,27 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch)
                return;
 
        n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel;
-
-       /* cache head and tail of queue */
-       head = circ->head & (UART_XMIT_SIZE - 1);
-       tail = circ->tail & (UART_XMIT_SIZE - 1);
-       qlen = uart_circ_chars_pending(circ);
+       qlen = kfifo_len(&tport->xmit_fifo);
 
        /* Find minimum of the FIFO space, versus queue length */
        n = min(n, qlen);
 
        while (n > 0) {
-
-               s = ((head >= tail) ? head : UART_XMIT_SIZE) - tail;
-               s = min(s, n);
-
+               s = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, n);
                if (s <= 0)
                        break;
 
-               memcpy_toio(&ch->ch_neo_uart->txrxburst, circ->buf + tail, s);
-               /* Add and flip queue if needed */
-               tail = (tail + s) & (UART_XMIT_SIZE - 1);
+               memcpy_toio(&ch->ch_neo_uart->txrxburst, tail, s);
+               kfifo_skip_count(&tport->xmit_fifo, s);
                n -= s;
                ch->ch_txcount += s;
                len_written += s;
        }
 
-       /* Update the final tail */
-       circ->tail = tail & (UART_XMIT_SIZE - 1);
-
        if (len_written >= ch->ch_t_tlevel)
                ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
 
-       if (uart_circ_empty(circ))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                uart_write_wakeup(&ch->uart_port);
 }
 
index 5efb2b593be333483afd79b52678e1e177cb9acf..b83eee37c17d4f51fb302ee76dd3c9146db94dbe 100644 (file)
@@ -257,10 +257,11 @@ static int max3100_handlerx(struct max3100_port *s, u16 rx)
 static void max3100_work(struct work_struct *w)
 {
        struct max3100_port *s = container_of(w, struct max3100_port, work);
+       struct tty_port *tport = &s->port.state->port;
+       unsigned char ch;
        int rxchars;
        u16 tx, rx;
        int conf, cconf, crts;
-       struct circ_buf *xmit = &s->port.state->xmit;
 
        dev_dbg(&s->spi->dev, "%s\n", __func__);
 
@@ -290,10 +291,9 @@ static void max3100_work(struct work_struct *w)
                                tx = s->port.x_char;
                                s->port.icount.tx++;
                                s->port.x_char = 0;
-                       } else if (!uart_circ_empty(xmit) &&
-                                  !uart_tx_stopped(&s->port)) {
-                               tx = xmit->buf[xmit->tail];
-                               uart_xmit_advance(&s->port, 1);
+                       } else if (!uart_tx_stopped(&s->port) &&
+                                       uart_fifo_get(&s->port, &ch)) {
+                               tx = ch;
                        }
                        if (tx != 0xffff) {
                                max3100_calc_parity(s, &tx);
@@ -307,13 +307,13 @@ static void max3100_work(struct work_struct *w)
                        tty_flip_buffer_push(&s->port.state->port);
                        rxchars = 0;
                }
-               if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                        uart_write_wakeup(&s->port);
 
        } while (!s->force_end_work &&
                 !freezing(current) &&
                 ((rx & MAX3100_R) ||
-                 (!uart_circ_empty(xmit) &&
+                 (!kfifo_is_empty(&tport->xmit_fifo) &&
                   !uart_tx_stopped(&s->port))));
 
        if (rxchars > 0)
index 14dd9cfaa9f76fc388500a637d171e90739291ea..f0eb96429dae47c3408628eb61f2dd1398d8b1a6 100644 (file)
@@ -747,8 +747,9 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
 
 static void max310x_handle_tx(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
-       unsigned int txlen, to_send, until_end;
+       struct tty_port *tport = &port->state->port;
+       unsigned int txlen, to_send;
+       unsigned char *tail;
 
        if (unlikely(port->x_char)) {
                max310x_port_write(port, MAX310X_THR_REG, port->x_char);
@@ -757,32 +758,26 @@ static void max310x_handle_tx(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))
                return;
 
-       /* Get length of data pending in circular buffer */
-       to_send = uart_circ_chars_pending(xmit);
-       until_end = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
-       if (likely(to_send)) {
+       /*
+        * It's a circ buffer -- wrap around.
+        * We could do that in one SPI transaction, but meh.
+        */
+       while (!kfifo_is_empty(&tport->xmit_fifo)) {
                /* Limit to space available in TX FIFO */
                txlen = max310x_port_read(port, MAX310X_TXFIFOLVL_REG);
                txlen = port->fifosize - txlen;
-               to_send = (to_send > txlen) ? txlen : to_send;
-
-               if (until_end < to_send) {
-                       /*
-                        * It's a circ buffer -- wrap around.
-                        * We could do that in one SPI transaction, but meh.
-                        */
-                       max310x_batch_write(port, xmit->buf + xmit->tail, until_end);
-                       max310x_batch_write(port, xmit->buf, to_send - until_end);
-               } else {
-                       max310x_batch_write(port, xmit->buf + xmit->tail, to_send);
-               }
+               if (!txlen)
+                       break;
+
+               to_send = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail, txlen);
+               max310x_batch_write(port, tail, to_send);
                uart_xmit_advance(port, to_send);
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 }
 
index 8048fa542fc45108a3b565db96ed72a383a8ba30..4bff422bb1bc36fb4faf5ec8dd4b38db91f34507 100644 (file)
@@ -293,17 +293,14 @@ static void men_z135_handle_rx(struct men_z135_port *uart)
 static void men_z135_handle_tx(struct men_z135_port *uart)
 {
        struct uart_port *port = &uart->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
+       unsigned char *tail;
+       unsigned int n, txfree;
        u32 txc;
        u32 wptr;
        int qlen;
-       int n;
-       int txfree;
-       int head;
-       int tail;
-       int s;
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                goto out;
 
        if (uart_tx_stopped(port))
@@ -313,7 +310,7 @@ static void men_z135_handle_tx(struct men_z135_port *uart)
                goto out;
 
        /* calculate bytes to copy */
-       qlen = uart_circ_chars_pending(xmit);
+       qlen = kfifo_len(&tport->xmit_fifo);
        if (qlen <= 0)
                goto out;
 
@@ -345,21 +342,18 @@ static void men_z135_handle_tx(struct men_z135_port *uart)
        if (n <= 0)
                goto irq_en;
 
-       head = xmit->head & (UART_XMIT_SIZE - 1);
-       tail = xmit->tail & (UART_XMIT_SIZE - 1);
-
-       s = ((head >= tail) ? head : UART_XMIT_SIZE) - tail;
-       n = min(n, s);
+       n = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
+                       min_t(unsigned int, UART_XMIT_SIZE, n));
+       memcpy_toio(port->membase + MEN_Z135_TX_RAM, tail, n);
 
-       memcpy_toio(port->membase + MEN_Z135_TX_RAM, &xmit->buf[xmit->tail], n);
        iowrite32(n & 0x3ff, port->membase + MEN_Z135_TX_CTRL);
        uart_xmit_advance(port, n);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
 irq_en:
-       if (!uart_circ_empty(xmit))
+       if (!kfifo_is_empty(&tport->xmit_fifo))
                men_z135_reg_set(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_TXCIEN);
        else
                men_z135_reg_clr(uart, MEN_Z135_CONF_REG, MEN_Z135_IER_TXCIEN);
index 6feac459c0cf4f7a2b6fff658023205d9fa81d78..4587ed4d4d5d048cef69c32042870ed5f9766eda 100644 (file)
@@ -141,8 +141,8 @@ static void meson_uart_shutdown(struct uart_port *port)
 
 static void meson_uart_start_tx(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
-       unsigned int ch;
+       struct tty_port *tport = &port->state->port;
+       unsigned char ch;
        u32 val;
 
        if (uart_tx_stopped(port)) {
@@ -158,21 +158,20 @@ static void meson_uart_start_tx(struct uart_port *port)
                        continue;
                }
 
-               if (uart_circ_empty(xmit))
+               if (!uart_fifo_get(port, &ch))
                        break;
 
-               ch = xmit->buf[xmit->tail];
                writel(ch, port->membase + AML_UART_WFIFO);
                uart_xmit_advance(port, 1);
        }
 
-       if (!uart_circ_empty(xmit)) {
+       if (!kfifo_is_empty(&tport->xmit_fifo)) {
                val = readl(port->membase + AML_UART_CONTROL);
                val |= AML_UART_TX_INT_EN;
                writel(val, port->membase + AML_UART_CONTROL);
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 }
 
index da4c6f7e2a308c9c4c546f23cae569bd613a59a6..fb082ee73d5b25c80a714d92b23d9bf94b2cefaa 100644 (file)
@@ -72,7 +72,7 @@ static void mlb_usio_stop_tx(struct uart_port *port)
 
 static void mlb_usio_tx_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        int count;
 
        writew(readw(port->membase + MLB_USIO_REG_FCR) & ~MLB_USIO_FCR_FTIE,
@@ -87,7 +87,7 @@ static void mlb_usio_tx_chars(struct uart_port *port)
                port->x_char = 0;
                return;
        }
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                mlb_usio_stop_tx(port);
                return;
        }
@@ -96,12 +96,13 @@ static void mlb_usio_tx_chars(struct uart_port *port)
                (readw(port->membase + MLB_USIO_REG_FBYTE) & 0xff);
 
        do {
-               writew(xmit->buf[xmit->tail], port->membase + MLB_USIO_REG_DR);
+               unsigned char ch;
 
-               uart_xmit_advance(port, 1);
-               if (uart_circ_empty(xmit))
+               if (!uart_fifo_get(port, &ch))
                        break;
 
+               writew(ch, port->membase + MLB_USIO_REG_DR);
+               port->icount.tx++;
        } while (--count > 0);
 
        writew(readw(port->membase + MLB_USIO_REG_FCR) & ~MLB_USIO_FCR_FDRQ,
@@ -110,10 +111,10 @@ static void mlb_usio_tx_chars(struct uart_port *port)
        writeb(readb(port->membase + MLB_USIO_REG_SCR) | MLB_USIO_SCR_TBIE,
               port->membase + MLB_USIO_REG_SCR);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                mlb_usio_stop_tx(port);
 }
 
index 7bf30e632313e7b27274ed36eadecc766ac86df0..ae7a8e3cf467acf3d46d8afd6a513f30bc4d081b 100644 (file)
@@ -452,7 +452,7 @@ static void msm_complete_tx_dma(void *args)
 {
        struct msm_port *msm_port = args;
        struct uart_port *port = &msm_port->uart;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct msm_dma *dma = &msm_port->tx_dma;
        struct dma_tx_state state;
        unsigned long flags;
@@ -486,7 +486,7 @@ static void msm_complete_tx_dma(void *args)
        msm_port->imr |= MSM_UART_IMR_TXLEV;
        msm_write(port, msm_port->imr, MSM_UART_IMR);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        msm_handle_tx(port);
@@ -496,14 +496,14 @@ done:
 
 static int msm_handle_tx_dma(struct msm_port *msm_port, unsigned int count)
 {
-       struct circ_buf *xmit = &msm_port->uart.state->xmit;
        struct uart_port *port = &msm_port->uart;
+       struct tty_port *tport = &port->state->port;
        struct msm_dma *dma = &msm_port->tx_dma;
        int ret;
        u32 val;
 
        sg_init_table(&dma->tx_sg, 1);
-       sg_set_buf(&dma->tx_sg, &xmit->buf[xmit->tail], count);
+       kfifo_dma_out_prepare(&tport->xmit_fifo, &dma->tx_sg, 1, count);
 
        ret = dma_map_sg(port->dev, &dma->tx_sg, 1, dma->dir);
        if (ret)
@@ -843,8 +843,8 @@ static void msm_handle_rx(struct uart_port *port)
 
 static void msm_handle_tx_pio(struct uart_port *port, unsigned int tx_count)
 {
-       struct circ_buf *xmit = &port->state->xmit;
        struct msm_port *msm_port = to_msm_port(port);
+       struct tty_port *tport = &port->state->port;
        unsigned int num_chars;
        unsigned int tf_pointer = 0;
        void __iomem *tf;
@@ -858,8 +858,7 @@ static void msm_handle_tx_pio(struct uart_port *port, unsigned int tx_count)
                msm_reset_dm_count(port, tx_count);
 
        while (tf_pointer < tx_count) {
-               int i;
-               char buf[4] = { 0 };
+               unsigned char buf[4] = { 0 };
 
                if (!(msm_read(port, MSM_UART_SR) & MSM_UART_SR_TX_READY))
                        break;
@@ -870,26 +869,23 @@ static void msm_handle_tx_pio(struct uart_port *port, unsigned int tx_count)
                else
                        num_chars = 1;
 
-               for (i = 0; i < num_chars; i++)
-                       buf[i] = xmit->buf[xmit->tail + i];
-
+               num_chars = uart_fifo_out(port, buf, num_chars);
                iowrite32_rep(tf, buf, 1);
-               uart_xmit_advance(port, num_chars);
                tf_pointer += num_chars;
        }
 
        /* disable tx interrupts if nothing more to send */
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                msm_stop_tx(port);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 }
 
 static void msm_handle_tx(struct uart_port *port)
 {
        struct msm_port *msm_port = to_msm_port(port);
-       struct circ_buf *xmit = &msm_port->uart.state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct msm_dma *dma = &msm_port->tx_dma;
        unsigned int pio_count, dma_count, dma_min;
        char buf[4] = { 0 };
@@ -913,13 +909,13 @@ static void msm_handle_tx(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                msm_stop_tx(port);
                return;
        }
 
-       pio_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
-       dma_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       dma_count = pio_count = kfifo_out_linear(&tport->xmit_fifo, NULL,
+                       UART_XMIT_SIZE);
 
        dma_min = 1;    /* Always DMA */
        if (msm_port->is_uartdm > UARTDM_1P3) {
index 0255646bc1752dd85b876694abbeaedb1909c87a..5de57b77abdb03f2fd46b2dc7f9bf7f00c34c15e 100644 (file)
@@ -219,12 +219,10 @@ static void mvebu_uart_stop_tx(struct uart_port *port)
 static void mvebu_uart_start_tx(struct uart_port *port)
 {
        unsigned int ctl;
-       struct circ_buf *xmit = &port->state->xmit;
+       unsigned char c;
 
-       if (IS_EXTENDED(port) && !uart_circ_empty(xmit)) {
-               writel(xmit->buf[xmit->tail], port->membase + UART_TSH(port));
-               uart_xmit_advance(port, 1);
-       }
+       if (IS_EXTENDED(port) && uart_fifo_get(port, &c))
+               writel(c, port->membase + UART_TSH(port));
 
        ctl = readl(port->membase + UART_INTR(port));
        ctl |= CTRL_TX_RDY_INT(port);
index 4749331fe618cad7c0af98630f90021b8244bd07..144b35d31497a5ac1ceabed10a35b1a3715b3440 100644 (file)
@@ -517,7 +517,7 @@ static void mxs_auart_tx_chars(struct mxs_auart_port *s);
 static void dma_tx_callback(void *param)
 {
        struct mxs_auart_port *s = param;
-       struct circ_buf *xmit = &s->port.state->xmit;
+       struct tty_port *tport = &s->port.state->port;
 
        dma_unmap_sg(s->dev, &s->tx_sgl, 1, DMA_TO_DEVICE);
 
@@ -526,7 +526,7 @@ static void dma_tx_callback(void *param)
        smp_mb__after_atomic();
 
        /* wake up the possible processes. */
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&s->port);
 
        mxs_auart_tx_chars(s);
@@ -568,33 +568,22 @@ 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;
+       struct tty_port *tport = &s->port.state->port;
        bool pending;
        u8 ch;
 
        if (auart_dma_enabled(s)) {
                u32 i = 0;
-               int size;
                void *buffer = s->tx_dma_buf;
 
                if (test_and_set_bit(MXS_AUART_DMA_TX_SYNC, &s->flags))
                        return;
 
-               while (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
-                       size = min_t(u32, UART_XMIT_SIZE - i,
-                                    CIRC_CNT_TO_END(xmit->head,
-                                                    xmit->tail,
-                                                    UART_XMIT_SIZE));
-                       memcpy(buffer + i, xmit->buf + xmit->tail, size);
-                       xmit->tail = (xmit->tail + size) & (UART_XMIT_SIZE - 1);
-
-                       i += size;
-                       if (i >= UART_XMIT_SIZE)
-                               break;
-               }
-
                if (uart_tx_stopped(&s->port))
                        mxs_auart_stop_tx(&s->port);
+               else
+                       i = kfifo_out(&tport->xmit_fifo, buffer,
+                                       UART_XMIT_SIZE);
 
                if (i) {
                        mxs_auart_dma_tx(s, i);
index 89257cddf540503d3d41a3d2de74f35e81486192..c7cee5fee60372d93330a77ebe76f8ec11b5ef3b 100644 (file)
@@ -808,7 +808,7 @@ static int dma_handle_rx(struct eg20t_port *priv)
 static unsigned int handle_tx(struct eg20t_port *priv)
 {
        struct uart_port *port = &priv->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       unsigned char ch;
        int fifo_size;
        int tx_empty;
 
@@ -830,9 +830,9 @@ static unsigned int handle_tx(struct eg20t_port *priv)
                fifo_size--;
        }
 
-       while (!uart_tx_stopped(port) && !uart_circ_empty(xmit) && fifo_size) {
-               iowrite8(xmit->buf[xmit->tail], priv->membase + PCH_UART_THR);
-               uart_xmit_advance(port, 1);
+       while (!uart_tx_stopped(port) && fifo_size &&
+                       uart_fifo_get(port, &ch)) {
+               iowrite8(ch, priv->membase + PCH_UART_THR);
                fifo_size--;
                tx_empty = 0;
        }
@@ -850,14 +850,14 @@ static unsigned int handle_tx(struct eg20t_port *priv)
 static unsigned int dma_handle_tx(struct eg20t_port *priv)
 {
        struct uart_port *port = &priv->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct scatterlist *sg;
        int nent;
        int fifo_size;
        struct dma_async_tx_descriptor *desc;
+       unsigned int bytes, tail;
        int num;
        int i;
-       int bytes;
        int size;
        int rem;
 
@@ -886,7 +886,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
                fifo_size--;
        }
 
-       bytes = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       bytes = kfifo_out_linear(&tport->xmit_fifo, &tail, UART_XMIT_SIZE);
        if (!bytes) {
                dev_dbg(priv->port.dev, "%s 0 bytes return\n", __func__);
                pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_TX_INT);
@@ -920,10 +920,10 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
 
        for (i = 0; i < num; i++, sg++) {
                if (i == (num - 1))
-                       sg_set_page(sg, virt_to_page(xmit->buf),
+                       sg_set_page(sg, virt_to_page(tport->xmit_buf),
                                    rem, fifo_size * i);
                else
-                       sg_set_page(sg, virt_to_page(xmit->buf),
+                       sg_set_page(sg, virt_to_page(tport->xmit_buf),
                                    size, fifo_size * i);
        }
 
@@ -937,8 +937,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
        priv->nent = nent;
 
        for (i = 0; i < nent; i++, sg++) {
-               sg->offset = (xmit->tail & (UART_XMIT_SIZE - 1)) +
-                             fifo_size * i;
+               sg->offset = tail + fifo_size * i;
                sg_dma_address(sg) = (sg_dma_address(sg) &
                                    ~(UART_XMIT_SIZE - 1)) + sg->offset;
                if (i == (nent - 1))
index bbb46e6e98a24fc24b172e8bc9642b497a3e70a5..f5af336a869bd5cf67ca9a80de3695ce2b0f0862 100644 (file)
@@ -342,7 +342,7 @@ static void pic32_uart_do_rx(struct uart_port *port)
 static void pic32_uart_do_tx(struct uart_port *port)
 {
        struct pic32_sport *sport = to_pic32_sport(port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        unsigned int max_count = PIC32_UART_TX_FIFO_DEPTH;
 
        if (port->x_char) {
@@ -357,7 +357,7 @@ static void pic32_uart_do_tx(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                goto txq_empty;
 
        /* keep stuffing chars into uart tx buffer
@@ -371,21 +371,20 @@ static void pic32_uart_do_tx(struct uart_port *port)
         */
        while (!(PIC32_UART_STA_UTXBF &
                pic32_uart_readl(sport, PIC32_UART_STA))) {
-               unsigned int c = xmit->buf[xmit->tail];
+               unsigned char c;
 
+               if (!uart_fifo_get(port, &c))
+                       break;
                pic32_uart_writel(sport, PIC32_UART_TX, c);
 
-               uart_xmit_advance(port, 1);
-               if (uart_circ_empty(xmit))
-                       break;
                if (--max_count == 0)
                        break;
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                goto txq_empty;
 
        return;
index 05d97e89511e698bee73698edd0a98a58893bb7b..63bc726273fd8d0b715d37e1a5e8b6171502efec 100644 (file)
@@ -347,7 +347,8 @@ static void pmz_status_handle(struct uart_pmac_port *uap)
 
 static void pmz_transmit_chars(struct uart_pmac_port *uap)
 {
-       struct circ_buf *xmit;
+       struct tty_port *tport;
+       unsigned char ch;
 
        if (ZS_IS_CONS(uap)) {
                unsigned char status = read_zsreg(uap, R0);
@@ -398,8 +399,8 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap)
 
        if (uap->port.state == NULL)
                goto ack_tx_int;
-       xmit = &uap->port.state->xmit;
-       if (uart_circ_empty(xmit)) {
+       tport = &uap->port.state->port;
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                uart_write_wakeup(&uap->port);
                goto ack_tx_int;
        }
@@ -407,12 +408,11 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap)
                goto ack_tx_int;
 
        uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
-       write_zsdata(uap, xmit->buf[xmit->tail]);
+       WARN_ON(!uart_fifo_get(&uap->port, &ch));
+       write_zsdata(uap, ch);
        zssync(uap);
 
-       uart_xmit_advance(&uap->port, 1);
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&uap->port);
 
        return;
@@ -620,15 +620,15 @@ static void pmz_start_tx(struct uart_port *port)
                port->icount.tx++;
                port->x_char = 0;
        } else {
-               struct circ_buf *xmit = &port->state->xmit;
+               struct tty_port *tport = &port->state->port;
+               unsigned char ch;
 
-               if (uart_circ_empty(xmit))
+               if (!uart_fifo_get(&uap->port, &ch))
                        return;
-               write_zsdata(uap, xmit->buf[xmit->tail]);
+               write_zsdata(uap, ch);
                zssync(uap);
-               uart_xmit_advance(port, 1);
 
-               if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                        uart_write_wakeup(&uap->port);
        }
 }
index f9f7ac1a10df3d668d41506075359c7601b12185..7814982f19215ca4d99f13f645d086505d634b5d 100644 (file)
@@ -505,7 +505,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
                 */
                qcom_geni_serial_poll_tx_done(uport);
 
-               if (!uart_circ_empty(&uport->state->xmit)) {
+               if (!kfifo_is_empty(&uport->state->port.xmit_fifo)) {
                        irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
                        writel(irq_en | M_TX_FIFO_WATERMARK_EN,
                                        uport->membase + SE_GENI_M_IRQ_EN);
@@ -620,22 +620,24 @@ static void qcom_geni_serial_stop_tx_dma(struct uart_port *uport)
 static void qcom_geni_serial_start_tx_dma(struct uart_port *uport)
 {
        struct qcom_geni_serial_port *port = to_dev_port(uport);
-       struct circ_buf *xmit = &uport->state->xmit;
+       struct tty_port *tport = &uport->state->port;
        unsigned int xmit_size;
+       u8 *tail;
        int ret;
 
        if (port->tx_dma_addr)
                return;
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                return;
 
-       xmit_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       xmit_size = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
+                       UART_XMIT_SIZE);
 
        qcom_geni_serial_setup_tx(uport, xmit_size);
 
-       ret = geni_se_tx_dma_prep(&port->se, &xmit->buf[xmit->tail],
-                                 xmit_size, &port->tx_dma_addr);
+       ret = geni_se_tx_dma_prep(&port->se, tail, xmit_size,
+                                 &port->tx_dma_addr);
        if (ret) {
                dev_err(uport->dev, "unable to start TX SE DMA: %d\n", ret);
                qcom_geni_serial_stop_tx_dma(uport);
@@ -853,18 +855,16 @@ static void 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;
-       unsigned int tx_bytes, c, remaining = chunk;
+       struct tty_port *tport = &uport->state->port;
+       unsigned int tx_bytes, remaining = chunk;
        u8 buf[BYTES_PER_FIFO_WORD];
 
        while (remaining) {
                memset(buf, 0, sizeof(buf));
                tx_bytes = min(remaining, BYTES_PER_FIFO_WORD);
 
-               for (c = 0; c < tx_bytes ; c++) {
-                       buf[c] = xmit->buf[xmit->tail];
-                       uart_xmit_advance(uport, 1);
-               }
+               tx_bytes = kfifo_out(&tport->xmit_fifo, buf, tx_bytes);
+               uart_xmit_advance(uport, tx_bytes);
 
                iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1);
 
@@ -877,7 +877,7 @@ static void qcom_geni_serial_handle_tx_fifo(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;
+       struct tty_port *tport = &uport->state->port;
        size_t avail;
        size_t pending;
        u32 status;
@@ -890,7 +890,7 @@ static void qcom_geni_serial_handle_tx_fifo(struct uart_port *uport,
        if (active)
                pending = port->tx_remaining;
        else
-               pending = uart_circ_chars_pending(xmit);
+               pending = kfifo_len(&tport->xmit_fifo);
 
        /* All data has been transmitted and acknowledged as received */
        if (!pending && !status && done) {
@@ -933,24 +933,24 @@ out_write_wakeup:
                                        uport->membase + SE_GENI_M_IRQ_EN);
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(uport);
 }
 
 static void qcom_geni_serial_handle_tx_dma(struct uart_port *uport)
 {
        struct qcom_geni_serial_port *port = to_dev_port(uport);
-       struct circ_buf *xmit = &uport->state->xmit;
+       struct tty_port *tport = &uport->state->port;
 
        uart_xmit_advance(uport, port->tx_remaining);
        geni_se_tx_dma_unprep(&port->se, port->tx_dma_addr, port->tx_remaining);
        port->tx_dma_addr = 0;
        port->tx_remaining = 0;
 
-       if (!uart_circ_empty(xmit))
+       if (!kfifo_is_empty(&tport->xmit_fifo))
                qcom_geni_serial_start_tx_dma(uport);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(uport);
 }
 
index 82def9b8632a56102470d3f45f170a4750f3541a..663e35e424bdb08b73d85a9ddebadf9b84ff0c6e 100644 (file)
@@ -330,8 +330,8 @@ static void rda_uart_set_termios(struct uart_port *port,
 
 static void rda_uart_send_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
-       unsigned int ch;
+       struct tty_port *tport = &port->state->port;
+       unsigned char ch;
        u32 val;
 
        if (uart_tx_stopped(port))
@@ -347,19 +347,14 @@ static void rda_uart_send_chars(struct uart_port *port)
                port->x_char = 0;
        }
 
-       while (rda_uart_read(port, RDA_UART_STATUS) & RDA_UART_TX_FIFO_MASK) {
-               if (uart_circ_empty(xmit))
-                       break;
-
-               ch = xmit->buf[xmit->tail];
+       while ((rda_uart_read(port, RDA_UART_STATUS) & RDA_UART_TX_FIFO_MASK) &&
+                       uart_fifo_get(port, &ch))
                rda_uart_write(port, ch, RDA_UART_RXTX_BUFFER);
-               uart_xmit_advance(port, 1);
-       }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (!uart_circ_empty(xmit)) {
+       if (!kfifo_is_empty(&tport->xmit_fifo)) {
                /* Re-enable Tx FIFO interrupt */
                val = rda_uart_read(port, RDA_UART_IRQ_MASK);
                val |= RDA_UART_TX_DATA_NEEDED;
index a2d07e05c50264063983be7e0fe9e0fea80678ca..dc35eb77d2ef34147b288cb264ece5eba00d7c63 100644 (file)
@@ -329,7 +329,7 @@ static void s3c24xx_serial_tx_dma_complete(void *args)
 {
        struct s3c24xx_uart_port *ourport = args;
        struct uart_port *port = &ourport->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct s3c24xx_uart_dma *dma = ourport->dma;
        struct dma_tx_state state;
        unsigned long flags;
@@ -348,7 +348,7 @@ static void s3c24xx_serial_tx_dma_complete(void *args)
        uart_xmit_advance(port, count);
        ourport->tx_in_progress = 0;
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        s3c24xx_serial_start_next_tx(ourport);
@@ -431,17 +431,15 @@ static void s3c24xx_serial_start_tx_pio(struct s3c24xx_uart_port *ourport)
 }
 
 static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport,
-                                     unsigned int count)
+                                     unsigned int count, unsigned int tail)
 {
-       struct uart_port *port = &ourport->port;
-       struct circ_buf *xmit = &port->state->xmit;
        struct s3c24xx_uart_dma *dma = ourport->dma;
 
        if (ourport->tx_mode != S3C24XX_TX_DMA)
                enable_tx_dma(ourport);
 
        dma->tx_size = count & ~(dma_get_cache_alignment() - 1);
-       dma->tx_transfer_addr = dma->tx_addr + xmit->tail;
+       dma->tx_transfer_addr = dma->tx_addr + tail;
 
        dma_sync_single_for_device(dma->tx_chan->device->dev,
                                   dma->tx_transfer_addr, dma->tx_size,
@@ -468,11 +466,11 @@ static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport,
 static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport)
 {
        struct uart_port *port = &ourport->port;
-       struct circ_buf *xmit = &port->state->xmit;
-       unsigned long count;
+       struct tty_port *tport = &port->state->port;
+       unsigned int count, tail;
 
        /* Get data size up to the end of buffer */
-       count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       count = kfifo_out_linear(&tport->xmit_fifo, &tail, UART_XMIT_SIZE);
 
        if (!count) {
                s3c24xx_serial_stop_tx(port);
@@ -481,16 +479,16 @@ static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport)
 
        if (!ourport->dma || !ourport->dma->tx_chan ||
            count < ourport->min_dma_size ||
-           xmit->tail & (dma_get_cache_alignment() - 1))
+           tail & (dma_get_cache_alignment() - 1))
                s3c24xx_serial_start_tx_pio(ourport);
        else
-               s3c24xx_serial_start_tx_dma(ourport, count);
+               s3c24xx_serial_start_tx_dma(ourport, count, tail);
 }
 
 static void s3c24xx_serial_start_tx(struct uart_port *port)
 {
        struct s3c24xx_uart_port *ourport = to_ourport(port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
        if (!ourport->tx_enabled) {
                if (port->flags & UPF_CONS_FLOW)
@@ -502,7 +500,8 @@ static void s3c24xx_serial_start_tx(struct uart_port *port)
        }
 
        if (ourport->dma && ourport->dma->tx_chan) {
-               if (!uart_circ_empty(xmit) && !ourport->tx_in_progress)
+               if (!kfifo_is_empty(&tport->xmit_fifo) &&
+                               !ourport->tx_in_progress)
                        s3c24xx_serial_start_next_tx(ourport);
        }
 }
@@ -868,18 +867,19 @@ static irqreturn_t s3c24xx_serial_rx_irq(int irq, void *dev_id)
 static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
 {
        struct uart_port *port = &ourport->port;
-       struct circ_buf *xmit = &port->state->xmit;
-       int count, dma_count = 0;
+       struct tty_port *tport = &port->state->port;
+       unsigned int count, dma_count = 0, tail;
 
-       count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       count = kfifo_out_linear(&tport->xmit_fifo, &tail, UART_XMIT_SIZE);
 
        if (ourport->dma && ourport->dma->tx_chan &&
            count >= ourport->min_dma_size) {
                int align = dma_get_cache_alignment() -
-                       (xmit->tail & (dma_get_cache_alignment() - 1));
+                       (tail & (dma_get_cache_alignment() - 1));
                if (count - align >= ourport->min_dma_size) {
                        dma_count = count - align;
                        count = align;
+                       tail += align;
                }
        }
 
@@ -894,7 +894,7 @@ static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
         * stopped, disable the uart and exit
         */
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                s3c24xx_serial_stop_tx(port);
                return;
        }
@@ -906,24 +906,25 @@ static void s3c24xx_serial_tx_chars(struct s3c24xx_uart_port *ourport)
                dma_count = 0;
        }
 
-       while (!uart_circ_empty(xmit) && count > 0) {
-               if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)
+       while (!(rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull)) {
+               unsigned char ch;
+
+               if (!uart_fifo_get(port, &ch))
                        break;
 
-               wr_reg(port, S3C2410_UTXH, xmit->buf[xmit->tail]);
-               uart_xmit_advance(port, 1);
+               wr_reg(port, S3C2410_UTXH, ch);
                count--;
        }
 
        if (!count && dma_count) {
-               s3c24xx_serial_start_tx_dma(ourport, dma_count);
+               s3c24xx_serial_start_tx_dma(ourport, dma_count, tail);
                return;
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                s3c24xx_serial_stop_tx(port);
 }
 
@@ -1118,7 +1119,8 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
 
        /* TX buffer */
        dma->tx_addr = dma_map_single(dma->tx_chan->device->dev,
-                                     p->port.state->xmit.buf, UART_XMIT_SIZE,
+                                     p->port.state->port.xmit_buf,
+                                     UART_XMIT_SIZE,
                                      DMA_TO_DEVICE);
        if (dma_mapping_error(dma->tx_chan->device->dev, dma->tx_addr)) {
                reason = "DMA mapping error for TX buffer";
index dbec29d9a6c37bd5f1e77ace5d42645b2b9eaf0a..b4e1b90e59608a7813866cde1b98be69782350db 100644 (file)
@@ -382,7 +382,8 @@ static void sbd_receive_chars(struct sbd_port *sport)
 static void sbd_transmit_chars(struct sbd_port *sport)
 {
        struct uart_port *uport = &sport->port;
-       struct circ_buf *xmit = &sport->port.state->xmit;
+       struct tty_port *tport = &sport->port.state->port;
+       unsigned char ch;
        unsigned int mask;
        int stop_tx;
 
@@ -395,19 +396,19 @@ static void sbd_transmit_chars(struct sbd_port *sport)
        }
 
        /* If nothing to do or stopped or hardware stopped.  */
-       stop_tx = (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port));
+       stop_tx = uart_tx_stopped(&sport->port) ||
+               !uart_fifo_get(&sport->port, &ch);
 
        /* Send char.  */
        if (!stop_tx) {
-               write_sbdchn(sport, R_DUART_TX_HOLD, xmit->buf[xmit->tail]);
-               uart_xmit_advance(&sport->port, 1);
+               write_sbdchn(sport, R_DUART_TX_HOLD, ch);
 
-               if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                        uart_write_wakeup(&sport->port);
        }
 
        /* Are we are done?  */
-       if (stop_tx || uart_circ_empty(xmit)) {
+       if (stop_tx || kfifo_is_empty(&tport->xmit_fifo)) {
                /* Disable tx interrupts.  */
                mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
                mask &= ~M_DUART_IMR_TX;
index 929206a9a6e1150f9ec9803240840cfe6c11a37a..c6983b7bd78c6c79b45dbeb83146f894e4d877c3 100644 (file)
@@ -676,9 +676,9 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,
 static void sc16is7xx_handle_tx(struct uart_port *port)
 {
        struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
-       struct circ_buf *xmit = &port->state->xmit;
-       unsigned int txlen, to_send, i;
+       struct tty_port *tport = &port->state->port;
        unsigned long flags;
+       unsigned int txlen;
 
        if (unlikely(port->x_char)) {
                sc16is7xx_port_write(port, SC16IS7XX_THR_REG, port->x_char);
@@ -687,40 +687,30 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                uart_port_lock_irqsave(port, &flags);
                sc16is7xx_stop_tx(port);
                uart_port_unlock_irqrestore(port, flags);
                return;
        }
 
-       /* Get length of data pending in circular buffer */
-       to_send = uart_circ_chars_pending(xmit);
-       if (likely(to_send)) {
-               /* Limit to space available in TX FIFO */
-               txlen = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG);
-               if (txlen > SC16IS7XX_FIFO_SIZE) {
-                       dev_err_ratelimited(port->dev,
-                               "chip reports %d free bytes in TX fifo, but it only has %d",
-                               txlen, SC16IS7XX_FIFO_SIZE);
-                       txlen = 0;
-               }
-               to_send = (to_send > txlen) ? txlen : to_send;
-
-               /* Convert to linear buffer */
-               for (i = 0; i < to_send; ++i) {
-                       s->buf[i] = xmit->buf[xmit->tail];
-                       uart_xmit_advance(port, 1);
-               }
-
-               sc16is7xx_fifo_write(port, s->buf, to_send);
+       /* Limit to space available in TX FIFO */
+       txlen = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG);
+       if (txlen > SC16IS7XX_FIFO_SIZE) {
+               dev_err_ratelimited(port->dev,
+                       "chip reports %d free bytes in TX fifo, but it only has %d",
+                       txlen, SC16IS7XX_FIFO_SIZE);
+               txlen = 0;
        }
 
+       txlen = uart_fifo_out(port, s->buf, txlen);
+       sc16is7xx_fifo_write(port, s->buf, txlen);
+
        uart_port_lock_irqsave(port, &flags);
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                sc16is7xx_stop_tx(port);
        else
                sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT);
index f24217a560d7a21a8d9c1048717129494a90bf38..6d1d142fd2161f4ab79a51be9125907f76461858 100644 (file)
@@ -439,7 +439,7 @@ static void sccnxp_handle_rx(struct uart_port *port)
 static void sccnxp_handle_tx(struct uart_port *port)
 {
        u8 sr;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct sccnxp_port *s = dev_get_drvdata(port->dev);
 
        if (unlikely(port->x_char)) {
@@ -449,7 +449,7 @@ static void sccnxp_handle_tx(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                /* Disable TX if FIFO is empty */
                if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXEMT) {
                        sccnxp_disable_irq(port, IMR_TXRDY);
@@ -461,16 +461,20 @@ static void sccnxp_handle_tx(struct uart_port *port)
                return;
        }
 
-       while (!uart_circ_empty(xmit)) {
+       while (1) {
+               unsigned char ch;
+
                sr = sccnxp_port_read(port, SCCNXP_SR_REG);
                if (!(sr & SR_TXRDY))
                        break;
 
-               sccnxp_port_write(port, SCCNXP_THR_REG, xmit->buf[xmit->tail]);
-               uart_xmit_advance(port, 1);
+               if (!uart_fifo_get(port, &ch))
+                       break;
+
+               sccnxp_port_write(port, SCCNXP_THR_REG, ch);
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 }
 
index 525f3a2f7bd47f9013115e379f227d990cc5d768..1183ca54ab9217559a88ee075a5f3c7bf94b101c 100644 (file)
@@ -484,18 +484,18 @@ static void tegra_uart_release_port(struct uart_port *u)
 
 static void tegra_uart_fill_tx_fifo(struct tegra_uart_port *tup, int max_bytes)
 {
-       struct circ_buf *xmit = &tup->uport.state->xmit;
+       unsigned char ch;
        int i;
 
        for (i = 0; i < max_bytes; i++) {
-               BUG_ON(uart_circ_empty(xmit));
                if (tup->cdata->tx_fifo_full_status) {
                        unsigned long lsr = tegra_uart_read(tup, UART_LSR);
                        if ((lsr & TEGRA_UART_LSR_TXFIFO_FULL))
                                break;
                }
-               tegra_uart_write(tup, xmit->buf[xmit->tail], UART_TX);
-               uart_xmit_advance(&tup->uport, 1);
+               if (WARN_ON_ONCE(!uart_fifo_get(&tup->uport, &ch)))
+                       break;
+               tegra_uart_write(tup, ch, UART_TX);
        }
 }
 
@@ -514,7 +514,7 @@ static void tegra_uart_start_pio_tx(struct tegra_uart_port *tup,
 static void tegra_uart_tx_dma_complete(void *args)
 {
        struct tegra_uart_port *tup = args;
-       struct circ_buf *xmit = &tup->uport.state->xmit;
+       struct tty_port *tport = &tup->uport.state->port;
        struct dma_tx_state state;
        unsigned long flags;
        unsigned int count;
@@ -525,7 +525,7 @@ static void tegra_uart_tx_dma_complete(void *args)
        uart_port_lock_irqsave(&tup->uport, &flags);
        uart_xmit_advance(&tup->uport, count);
        tup->tx_in_progress = 0;
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&tup->uport);
        tegra_uart_start_next_tx(tup);
        uart_port_unlock_irqrestore(&tup->uport, flags);
@@ -534,11 +534,14 @@ static void tegra_uart_tx_dma_complete(void *args)
 static int tegra_uart_start_tx_dma(struct tegra_uart_port *tup,
                unsigned long count)
 {
-       struct circ_buf *xmit = &tup->uport.state->xmit;
+       struct tty_port *tport = &tup->uport.state->port;
        dma_addr_t tx_phys_addr;
+       unsigned int tail;
 
        tup->tx_bytes = count & ~(0xF);
-       tx_phys_addr = tup->tx_dma_buf_phys + xmit->tail;
+       WARN_ON_ONCE(kfifo_out_linear(&tport->xmit_fifo, &tail,
+                       UART_XMIT_SIZE) < count);
+       tx_phys_addr = tup->tx_dma_buf_phys + tail;
 
        dma_sync_single_for_device(tup->uport.dev, tx_phys_addr,
                                   tup->tx_bytes, DMA_TO_DEVICE);
@@ -562,18 +565,21 @@ static int tegra_uart_start_tx_dma(struct tegra_uart_port *tup,
 
 static void tegra_uart_start_next_tx(struct tegra_uart_port *tup)
 {
+       struct tty_port *tport = &tup->uport.state->port;
+       unsigned char *tail_ptr;
        unsigned long tail;
-       unsigned long count;
-       struct circ_buf *xmit = &tup->uport.state->xmit;
+       unsigned int count;
 
        if (!tup->current_baud)
                return;
 
-       tail = (unsigned long)&xmit->buf[xmit->tail];
-       count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       count = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail_ptr,
+                       UART_XMIT_SIZE);
        if (!count)
                return;
 
+       tail = (unsigned long)tail_ptr;
+
        if (tup->use_tx_pio || count < TEGRA_UART_MIN_DMA)
                tegra_uart_start_pio_tx(tup, count);
        else if (BYTES_TO_ALIGN(tail) > 0)
@@ -586,9 +592,9 @@ static void tegra_uart_start_next_tx(struct tegra_uart_port *tup)
 static void tegra_uart_start_tx(struct uart_port *u)
 {
        struct tegra_uart_port *tup = to_tegra_uport(u);
-       struct circ_buf *xmit = &u->state->xmit;
+       struct tty_port *tport = &u->state->port;
 
-       if (!uart_circ_empty(xmit) && !tup->tx_in_progress)
+       if (!kfifo_is_empty(&tport->xmit_fifo) && !tup->tx_in_progress)
                tegra_uart_start_next_tx(tup);
 }
 
@@ -628,11 +634,11 @@ static void tegra_uart_stop_tx(struct uart_port *u)
 
 static void tegra_uart_handle_tx_pio(struct tegra_uart_port *tup)
 {
-       struct circ_buf *xmit = &tup->uport.state->xmit;
+       struct tty_port *tport = &tup->uport.state->port;
 
        tegra_uart_fill_tx_fifo(tup, tup->tx_bytes);
        tup->tx_in_progress = 0;
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&tup->uport);
        tegra_uart_start_next_tx(tup);
 }
@@ -1169,15 +1175,14 @@ static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup,
                tup->rx_dma_buf_virt = dma_buf;
                tup->rx_dma_buf_phys = dma_phys;
        } else {
+               dma_buf = tup->uport.state->port.xmit_buf;
                dma_phys = dma_map_single(tup->uport.dev,
-                       tup->uport.state->xmit.buf, UART_XMIT_SIZE,
-                       DMA_TO_DEVICE);
+                       dma_buf, UART_XMIT_SIZE, DMA_TO_DEVICE);
                if (dma_mapping_error(tup->uport.dev, dma_phys)) {
                        dev_err(tup->uport.dev, "dma_map_single tx failed\n");
                        dma_release_channel(dma_chan);
                        return -ENOMEM;
                }
-               dma_buf = tup->uport.state->xmit.buf;
                dma_sconfig.dst_addr = tup->uport.mapbase;
                dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
                dma_sconfig.dst_maxburst = 16;
index ff85ebd3a007dba0105e38d732efc0f6a6f8ab5b..3c0931fba1c6845c98a09b340d08c596e5e24d07 100644 (file)
@@ -272,9 +272,10 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
                return -ENOMEM;
 
        uart_port_lock(state, flags);
-       if (!state->xmit.buf) {
-               state->xmit.buf = (unsigned char *) page;
-               uart_circ_clear(&state->xmit);
+       if (!state->port.xmit_buf) {
+               state->port.xmit_buf = (unsigned char *)page;
+               kfifo_init(&state->port.xmit_fifo, state->port.xmit_buf,
+                               PAGE_SIZE);
                uart_port_unlock(uport, flags);
        } else {
                uart_port_unlock(uport, flags);
@@ -387,8 +388,9 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
         * can endup in printk() recursion.
         */
        uart_port_lock(state, flags);
-       xmit_buf = state->xmit.buf;
-       state->xmit.buf = NULL;
+       xmit_buf = port->xmit_buf;
+       port->xmit_buf = NULL;
+       INIT_KFIFO(port->xmit_fifo);
        uart_port_unlock(uport, flags);
 
        free_page((unsigned long)xmit_buf);
@@ -552,22 +554,17 @@ static int uart_put_char(struct tty_struct *tty, u8 c)
 {
        struct uart_state *state = tty->driver_data;
        struct uart_port *port;
-       struct circ_buf *circ;
        unsigned long flags;
        int ret = 0;
 
-       circ = &state->xmit;
        port = uart_port_lock(state, flags);
-       if (!circ->buf) {
+       if (WARN_ON_ONCE(!state->port.xmit_buf)) {
                uart_port_unlock(port, flags);
                return 0;
        }
 
-       if (port && uart_circ_chars_free(circ) != 0) {
-               circ->buf[circ->head] = c;
-               circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
-               ret = 1;
-       }
+       if (port)
+               ret = kfifo_put(&state->port.xmit_fifo, c);
        uart_port_unlock(port, flags);
        return ret;
 }
@@ -581,9 +578,8 @@ static ssize_t uart_write(struct tty_struct *tty, const u8 *buf, size_t count)
 {
        struct uart_state *state = tty->driver_data;
        struct uart_port *port;
-       struct circ_buf *circ;
        unsigned long flags;
-       int c, ret = 0;
+       int ret = 0;
 
        /*
         * This means you called this function _after_ the port was
@@ -593,24 +589,13 @@ static ssize_t uart_write(struct tty_struct *tty, const u8 *buf, size_t count)
                return -EL3HLT;
 
        port = uart_port_lock(state, flags);
-       circ = &state->xmit;
-       if (!circ->buf) {
+       if (WARN_ON_ONCE(!state->port.xmit_buf)) {
                uart_port_unlock(port, flags);
                return 0;
        }
 
-       while (port) {
-               c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
-               if (count < c)
-                       c = count;
-               if (c <= 0)
-                       break;
-               memcpy(circ->buf + circ->head, buf, c);
-               circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
-               buf += c;
-               count -= c;
-               ret += c;
-       }
+       if (port)
+               ret = kfifo_in(&state->port.xmit_fifo, buf, count);
 
        __uart_start(state);
        uart_port_unlock(port, flags);
@@ -625,7 +610,7 @@ static unsigned int uart_write_room(struct tty_struct *tty)
        unsigned int ret;
 
        port = uart_port_lock(state, flags);
-       ret = uart_circ_chars_free(&state->xmit);
+       ret = kfifo_avail(&state->port.xmit_fifo);
        uart_port_unlock(port, flags);
        return ret;
 }
@@ -638,7 +623,7 @@ static unsigned int uart_chars_in_buffer(struct tty_struct *tty)
        unsigned int ret;
 
        port = uart_port_lock(state, flags);
-       ret = uart_circ_chars_pending(&state->xmit);
+       ret = kfifo_len(&state->port.xmit_fifo);
        uart_port_unlock(port, flags);
        return ret;
 }
@@ -661,7 +646,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
        port = uart_port_lock(state, flags);
        if (!port)
                return;
-       uart_circ_clear(&state->xmit);
+       kfifo_reset(&state->port.xmit_fifo);
        if (port->ops->flush_buffer)
                port->ops->flush_buffer(port);
        uart_port_unlock(port, flags);
@@ -1064,7 +1049,7 @@ static int uart_get_lsr_info(struct tty_struct *tty,
         * interrupt happens).
         */
        if (uport->x_char ||
-           ((uart_circ_chars_pending(&state->xmit) > 0) &&
+           (!kfifo_is_empty(&state->port.xmit_fifo) &&
             !uart_tx_stopped(uport)))
                result &= ~TIOCSER_TEMT;
 
@@ -1788,8 +1773,9 @@ static void uart_tty_port_shutdown(struct tty_port *port)
         * Free the transmit buffer.
         */
        uart_port_lock_irq(uport);
-       buf = state->xmit.buf;
-       state->xmit.buf = NULL;
+       buf = port->xmit_buf;
+       port->xmit_buf = NULL;
+       INIT_KFIFO(port->xmit_fifo);
        uart_port_unlock_irq(uport);
 
        free_page((unsigned long)buf);
index 22b9eeb23e68adb2cfd949ff20c18816bb78b1cb..3408c8827561e4312e65dcd061c53489737be473 100644 (file)
@@ -23,7 +23,7 @@
 static int __serial_port_busy(struct uart_port *port)
 {
        return !uart_tx_stopped(port) &&
-               uart_circ_chars_pending(&port->state->xmit);
+               !kfifo_is_empty(&port->state->port.xmit_fifo);
 }
 
 static int serial_port_runtime_resume(struct device *dev)
index e512eaa57ed562eb758d8da2ca34010ca753c022..97031db26ae4a4ca405bdf86716379e27feb507f 100644 (file)
@@ -585,7 +585,7 @@ static void sci_start_tx(struct uart_port *port)
                        sci_serial_out(port, SCSCR, new);
        }
 
-       if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
+       if (s->chan_tx && !kfifo_is_empty(&port->state->port.xmit_fifo) &&
            dma_submit_error(s->cookie_tx)) {
                if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
                        /* Switch irq from SCIF to DMA */
@@ -817,7 +817,7 @@ static int sci_rxfill(struct uart_port *port)
 
 static void sci_transmit_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        unsigned int stopped = uart_tx_stopped(port);
        unsigned short status;
        unsigned short ctrl;
@@ -826,7 +826,7 @@ static void sci_transmit_chars(struct uart_port *port)
        status = sci_serial_in(port, SCxSR);
        if (!(status & SCxSR_TDxE(port))) {
                ctrl = sci_serial_in(port, SCSCR);
-               if (uart_circ_empty(xmit))
+               if (kfifo_is_empty(&tport->xmit_fifo))
                        ctrl &= ~SCSCR_TIE;
                else
                        ctrl |= SCSCR_TIE;
@@ -842,15 +842,14 @@ static void sci_transmit_chars(struct uart_port *port)
                if (port->x_char) {
                        c = port->x_char;
                        port->x_char = 0;
-               } else if (!uart_circ_empty(xmit) && !stopped) {
-                       c = xmit->buf[xmit->tail];
-                       xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               } else if (port->type == PORT_SCI && uart_circ_empty(xmit)) {
-                       ctrl = sci_serial_in(port, SCSCR);
-                       ctrl &= ~SCSCR_TE;
-                       sci_serial_out(port, SCSCR, ctrl);
-                       return;
-               } else {
+               } else if (stopped || !kfifo_get(&tport->xmit_fifo, &c)) {
+                       if (port->type == PORT_SCI &&
+                                  kfifo_is_empty(&tport->xmit_fifo)) {
+                               ctrl = sci_serial_in(port, SCSCR);
+                               ctrl &= ~SCSCR_TE;
+                               sci_serial_out(port, SCSCR, ctrl);
+                               return;
+                       }
                        break;
                }
 
@@ -861,9 +860,9 @@ static void sci_transmit_chars(struct uart_port *port)
 
        sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                if (port->type == PORT_SCI) {
                        ctrl = sci_serial_in(port, SCSCR);
                        ctrl &= ~SCSCR_TIE;
@@ -1199,7 +1198,7 @@ static void sci_dma_tx_complete(void *arg)
 {
        struct sci_port *s = arg;
        struct uart_port *port = &s->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        unsigned long flags;
 
        dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
@@ -1208,10 +1207,10 @@ static void sci_dma_tx_complete(void *arg)
 
        uart_xmit_advance(port, s->tx_dma_len);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (!uart_circ_empty(xmit)) {
+       if (!kfifo_is_empty(&tport->xmit_fifo)) {
                s->cookie_tx = 0;
                schedule_work(&s->work_tx);
        } else {
@@ -1424,10 +1423,10 @@ static void sci_dma_tx_work_fn(struct work_struct *work)
        struct dma_async_tx_descriptor *desc;
        struct dma_chan *chan = s->chan_tx;
        struct uart_port *port = &s->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        unsigned long flags;
+       unsigned int tail;
        dma_addr_t buf;
-       int head, tail;
 
        /*
         * DMA is idle now.
@@ -1437,10 +1436,9 @@ static void sci_dma_tx_work_fn(struct work_struct *work)
         * consistent xmit buffer state.
         */
        uart_port_lock_irq(port);
-       head = xmit->head;
-       tail = xmit->tail;
+       s->tx_dma_len = kfifo_out_linear(&tport->xmit_fifo, &tail,
+                       UART_XMIT_SIZE);
        buf = s->tx_dma_addr + tail;
-       s->tx_dma_len = CIRC_CNT_TO_END(head, tail, UART_XMIT_SIZE);
        if (!s->tx_dma_len) {
                /* Transmit buffer has been flushed */
                uart_port_unlock_irq(port);
@@ -1469,8 +1467,8 @@ static void sci_dma_tx_work_fn(struct work_struct *work)
        }
 
        uart_port_unlock_irq(port);
-       dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n",
-               __func__, xmit->buf, tail, head, s->cookie_tx);
+       dev_dbg(port->dev, "%s: %p: %u, cookie %d\n",
+               __func__, tport->xmit_buf, tail, s->cookie_tx);
 
        dma_async_issue_pending(chan);
        return;
@@ -1585,6 +1583,7 @@ static struct dma_chan *sci_request_dma_chan(struct uart_port *port,
 static void sci_request_dma(struct uart_port *port)
 {
        struct sci_port *s = to_sci_port(port);
+       struct tty_port *tport = &port->state->port;
        struct dma_chan *chan;
 
        dev_dbg(port->dev, "%s: port %d\n", __func__, port->line);
@@ -1613,7 +1612,7 @@ static void sci_request_dma(struct uart_port *port)
        if (chan) {
                /* UART circular tx buffer is an aligned page. */
                s->tx_dma_addr = dma_map_single(chan->device->dev,
-                                               port->state->xmit.buf,
+                                               tport->xmit_buf,
                                                UART_XMIT_SIZE,
                                                DMA_TO_DEVICE);
                if (dma_mapping_error(chan->device->dev, s->tx_dma_addr)) {
@@ -1622,7 +1621,7 @@ static void sci_request_dma(struct uart_port *port)
                } else {
                        dev_dbg(port->dev, "%s: mapped %lu@%p to %pad\n",
                                __func__, UART_XMIT_SIZE,
-                               port->state->xmit.buf, &s->tx_dma_addr);
+                               tport->xmit_buf, &s->tx_dma_addr);
 
                        INIT_WORK(&s->work_tx, sci_dma_tx_work_fn);
                        s->chan_tx_saved = s->chan_tx = chan;
index 15f14fa593da58793a7cdbed5d7be07853f18ec9..3fc54cc02a1fc5242d06f8f9392966dd847208f8 100644 (file)
@@ -227,13 +227,13 @@ static int sprd_tx_buf_remap(struct uart_port *port)
 {
        struct sprd_uart_port *sp =
                container_of(port, struct sprd_uart_port, port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
+       unsigned char *tail;
 
-       sp->tx_dma.trans_len =
-               CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+       sp->tx_dma.trans_len = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
+                       UART_XMIT_SIZE);
 
-       sp->tx_dma.phys_addr = dma_map_single(port->dev,
-                                             (void *)&(xmit->buf[xmit->tail]),
+       sp->tx_dma.phys_addr = dma_map_single(port->dev, tail,
                                              sp->tx_dma.trans_len,
                                              DMA_TO_DEVICE);
        return dma_mapping_error(port->dev, sp->tx_dma.phys_addr);
@@ -244,7 +244,7 @@ static void sprd_complete_tx_dma(void *data)
        struct uart_port *port = (struct uart_port *)data;
        struct sprd_uart_port *sp =
                container_of(port, struct sprd_uart_port, port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        unsigned long flags;
 
        uart_port_lock_irqsave(port, &flags);
@@ -253,10 +253,10 @@ static void sprd_complete_tx_dma(void *data)
 
        uart_xmit_advance(port, sp->tx_dma.trans_len);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit) || sprd_tx_buf_remap(port) ||
+       if (kfifo_is_empty(&tport->xmit_fifo) || sprd_tx_buf_remap(port) ||
            sprd_tx_dma_config(port))
                sp->tx_dma.trans_len = 0;
 
@@ -319,7 +319,7 @@ static void sprd_start_tx_dma(struct uart_port *port)
 {
        struct sprd_uart_port *sp =
                container_of(port, struct sprd_uart_port, port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
        if (port->x_char) {
                serial_out(port, SPRD_TXD, port->x_char);
@@ -328,7 +328,7 @@ static void sprd_start_tx_dma(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                sprd_stop_tx_dma(port);
                return;
        }
index a23e5955184885fa51dbdf302b9b39968561aaa2..f91753a40a69b5684e9688b03bdf3dc59a683b8f 100644 (file)
@@ -387,9 +387,9 @@ static unsigned int asc_get_mctrl(struct uart_port *port)
 /* There are probably characters waiting to be transmitted. */
 static void asc_start_tx(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
-       if (!uart_circ_empty(xmit))
+       if (!kfifo_is_empty(&tport->xmit_fifo))
                asc_enable_tx_interrupts(port);
 }
 
index 58d169e5c1db03b910686ac2a229116644f0d6e9..8c66abcfe6ca9c36cefd79f2334828f8f7292939 100644 (file)
@@ -696,18 +696,23 @@ static void stm32_usart_transmit_chars_pio(struct uart_port *port)
 {
        struct stm32_port *stm32_port = to_stm32_port(port);
        const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
+
+       while (1) {
+               unsigned char ch;
 
-       while (!uart_circ_empty(xmit)) {
                /* Check that TDR is empty before filling FIFO */
                if (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE))
                        break;
-               writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
-               uart_xmit_advance(port, 1);
+
+               if (!uart_fifo_get(port, &ch))
+                       break;
+
+               writel_relaxed(ch, port->membase + ofs->tdr);
        }
 
        /* rely on TXE irq (mask or unmask) for sending remaining data */
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                stm32_usart_tx_interrupt_disable(port);
        else
                stm32_usart_tx_interrupt_enable(port);
@@ -716,7 +721,7 @@ static void stm32_usart_transmit_chars_pio(struct uart_port *port)
 static void stm32_usart_transmit_chars_dma(struct uart_port *port)
 {
        struct stm32_port *stm32port = to_stm32_port(port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        struct dma_async_tx_descriptor *desc = NULL;
        unsigned int count;
        int ret;
@@ -728,25 +733,8 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port)
                return;
        }
 
-       count = uart_circ_chars_pending(xmit);
-
-       if (count > TX_BUF_L)
-               count = TX_BUF_L;
-
-       if (xmit->tail < xmit->head) {
-               memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], count);
-       } else {
-               size_t one = UART_XMIT_SIZE - xmit->tail;
-               size_t two;
-
-               if (one > count)
-                       one = count;
-               two = count - one;
-
-               memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], one);
-               if (two)
-                       memcpy(&stm32port->tx_buf[one], &xmit->buf[0], two);
-       }
+       count = kfifo_out_peek(&tport->xmit_fifo, &stm32port->tx_buf[0],
+                       TX_BUF_L);
 
        desc = dmaengine_prep_slave_single(stm32port->tx_ch,
                                           stm32port->tx_dma_buf,
@@ -792,14 +780,14 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
 {
        struct stm32_port *stm32_port = to_stm32_port(port);
        const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        u32 isr;
        int ret;
 
        if (!stm32_port->hw_flow_control &&
            port->rs485.flags & SER_RS485_ENABLED &&
            (port->x_char ||
-            !(uart_circ_empty(xmit) || uart_tx_stopped(port)))) {
+            !(kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)))) {
                stm32_usart_tc_interrupt_disable(port);
                stm32_usart_rs485_rts_enable(port);
        }
@@ -826,7 +814,7 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                stm32_usart_tx_interrupt_disable(port);
                return;
        }
@@ -841,10 +829,10 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
        else
                stm32_usart_transmit_chars_pio(port);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                stm32_usart_tx_interrupt_disable(port);
                if (!stm32_port->hw_flow_control &&
                    port->rs485.flags & SER_RS485_ENABLED) {
@@ -967,9 +955,9 @@ static void stm32_usart_stop_tx(struct uart_port *port)
 /* There are probably characters waiting to be transmitted. */
 static void stm32_usart_start_tx(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
-       if (uart_circ_empty(xmit) && !port->x_char) {
+       if (kfifo_is_empty(&tport->xmit_fifo) && !port->x_char) {
                stm32_usart_rs485_rts_disable(port);
                return;
        }
index 8d612ab80680c9e54aec4d694430fa099e8a1c69..7f60679fdde1971b3af905dc72237a076e7f63ab 100644 (file)
@@ -39,10 +39,13 @@ static char *con_read_page;
 
 static int hung_up = 0;
 
-static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit)
+static void transmit_chars_putchar(struct uart_port *port,
+               struct tty_port *tport)
 {
-       while (!uart_circ_empty(xmit)) {
-               long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
+       unsigned char ch;
+
+       while (kfifo_peek(&tport->xmit_fifo, &ch)) {
+               long status = sun4v_con_putchar(ch);
 
                if (status != HV_EOK)
                        break;
@@ -51,14 +54,16 @@ static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit
        }
 }
 
-static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit)
+static void transmit_chars_write(struct uart_port *port, struct tty_port *tport)
 {
-       while (!uart_circ_empty(xmit)) {
-               unsigned long ra = __pa(xmit->buf + xmit->tail);
-               unsigned long len, status, sent;
+       while (!kfifo_is_empty(&tport->xmit_fifo)) {
+               unsigned long len, ra, status, sent;
+               unsigned char *tail;
+
+               len = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
+                               UART_XMIT_SIZE);
+               ra = __pa(tail);
 
-               len = CIRC_CNT_TO_END(xmit->head, xmit->tail,
-                                     UART_XMIT_SIZE);
                status = sun4v_con_write(ra, len, &sent);
                if (status != HV_EOK)
                        break;
@@ -165,7 +170,7 @@ static int receive_chars_read(struct uart_port *port)
 }
 
 struct sunhv_ops {
-       void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit);
+       void (*transmit_chars)(struct uart_port *port, struct tty_port *tport);
        int (*receive_chars)(struct uart_port *port);
 };
 
@@ -196,18 +201,18 @@ static struct tty_port *receive_chars(struct uart_port *port)
 
 static void transmit_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit;
+       struct tty_port *tport;
 
        if (!port->state)
                return;
 
-       xmit = &port->state->xmit;
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+       tport = &port->state->port;
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))
                return;
 
-       sunhv_ops->transmit_chars(port, xmit);
+       sunhv_ops->transmit_chars(port, tport);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 }
 
index f5e29eb4a4ce441911494795aa00fb1221ad17e6..abf7c449308d9f32b7106fd2bc276550578179a7 100644 (file)
@@ -200,7 +200,7 @@ static void sunplus_break_ctl(struct uart_port *port, int ctl)
 
 static void transmit_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
        if (port->x_char) {
                sp_uart_put_char(port, port->x_char);
@@ -209,22 +209,24 @@ static void transmit_chars(struct uart_port *port)
                return;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                sunplus_stop_tx(port);
                return;
        }
 
        do {
-               sp_uart_put_char(port, xmit->buf[xmit->tail]);
-               uart_xmit_advance(port, 1);
-               if (uart_circ_empty(xmit))
+               unsigned char ch;
+
+               if (!uart_fifo_get(port, &ch))
                        break;
+
+               sp_uart_put_char(port, ch);
        } while (sunplus_tx_buf_not_full(port));
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                sunplus_stop_tx(port);
 }
 
index 1ea2f33a07a74149669b2df514fc2a2a8fc83b0f..1acbe2fba746f948c6d913799bd631c00e8919f7 100644 (file)
@@ -232,7 +232,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *);
 static void transmit_chars(struct uart_sunsab_port *up,
                           union sab82532_irq_status *stat)
 {
-       struct circ_buf *xmit = &up->port.state->xmit;
+       struct tty_port *tport = &up->port.state->port;
        int i;
 
        if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) {
@@ -252,7 +252,7 @@ static void transmit_chars(struct uart_sunsab_port *up,
        set_bit(SAB82532_XPR, &up->irqflags);
        sunsab_tx_idle(up);
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(&up->port)) {
                up->interrupt_mask1 |= SAB82532_IMR1_XPR;
                writeb(up->interrupt_mask1, &up->regs->w.imr1);
                return;
@@ -265,21 +265,22 @@ static void transmit_chars(struct uart_sunsab_port *up,
        /* Stuff 32 bytes into Transmit FIFO. */
        clear_bit(SAB82532_XPR, &up->irqflags);
        for (i = 0; i < up->port.fifosize; i++) {
-               writeb(xmit->buf[xmit->tail],
-                      &up->regs->w.xfifo[i]);
-               uart_xmit_advance(&up->port, 1);
-               if (uart_circ_empty(xmit))
+               unsigned char ch;
+
+               if (!uart_fifo_get(&up->port, &ch))
                        break;
+
+               writeb(ch, &up->regs->w.xfifo[i]);
        }
 
        /* Issue a Transmit Frame command. */
        sunsab_cec_wait(up);
        writeb(SAB82532_CMDR_XF, &up->regs->w.cmdr);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&up->port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                sunsab_stop_tx(&up->port);
 }
 
@@ -435,10 +436,10 @@ static void sunsab_start_tx(struct uart_port *port)
 {
        struct uart_sunsab_port *up =
                container_of(port, struct uart_sunsab_port, port);
-       struct circ_buf *xmit = &up->port.state->xmit;
+       struct tty_port *tport = &up->port.state->port;
        int i;
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))
                return;
 
        up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR);
@@ -451,11 +452,12 @@ static void sunsab_start_tx(struct uart_port *port)
        clear_bit(SAB82532_XPR, &up->irqflags);
 
        for (i = 0; i < up->port.fifosize; i++) {
-               writeb(xmit->buf[xmit->tail],
-                      &up->regs->w.xfifo[i]);
-               uart_xmit_advance(&up->port, 1);
-               if (uart_circ_empty(xmit))
+               unsigned char ch;
+
+               if (!uart_fifo_get(&up->port, &ch))
                        break;
+
+               writeb(ch, &up->regs->w.xfifo[i]);
        }
 
        /* Issue a Transmit Frame command.  */
index c8b65f4b2710e47f361d578d639d3ef9bd114107..67a5fc70bb4b9053e4beea14a6636b29cf33c1a5 100644 (file)
@@ -396,7 +396,8 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status)
 
 static void transmit_chars(struct uart_sunsu_port *up)
 {
-       struct circ_buf *xmit = &up->port.state->xmit;
+       struct tty_port *tport = &up->port.state->port;
+       unsigned char ch;
        int count;
 
        if (up->port.x_char) {
@@ -409,23 +410,23 @@ static void transmit_chars(struct uart_sunsu_port *up)
                sunsu_stop_tx(&up->port);
                return;
        }
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                __stop_tx(up);
                return;
        }
 
        count = up->port.fifosize;
        do {
-               serial_out(up, UART_TX, xmit->buf[xmit->tail]);
-               uart_xmit_advance(&up->port, 1);
-               if (uart_circ_empty(xmit))
+               if (!uart_fifo_get(&up->port, &ch))
                        break;
+
+               serial_out(up, UART_TX, ch);
        } while (--count > 0);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&up->port);
 
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                __stop_tx(up);
 }
 
index c99289c6c8f89b7d7bd0a9459ed502efb805c474..71758ad4241c17681c144f45fbc02e1e1959412f 100644 (file)
@@ -453,7 +453,8 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
 static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
                                    struct zilog_channel __iomem *channel)
 {
-       struct circ_buf *xmit;
+       struct tty_port *tport;
+       unsigned char ch;
 
        if (ZS_IS_CONS(up)) {
                unsigned char status = readb(&channel->control);
@@ -496,21 +497,20 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
 
        if (up->port.state == NULL)
                goto ack_tx_int;
-       xmit = &up->port.state->xmit;
-       if (uart_circ_empty(xmit))
-               goto ack_tx_int;
+       tport = &up->port.state->port;
 
        if (uart_tx_stopped(&up->port))
                goto ack_tx_int;
 
+       if (!uart_fifo_get(&up->port, &ch))
+               goto ack_tx_int;
+
        up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
-       writeb(xmit->buf[xmit->tail], &channel->data);
+       writeb(ch, &channel->data);
        ZSDELAY();
        ZS_WSYNC(channel);
 
-       uart_xmit_advance(&up->port, 1);
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&up->port);
 
        return;
@@ -700,17 +700,16 @@ static void sunzilog_start_tx(struct uart_port *port)
                port->icount.tx++;
                port->x_char = 0;
        } else {
-               struct circ_buf *xmit = &port->state->xmit;
+               struct tty_port *tport = &port->state->port;
+               unsigned char ch;
 
-               if (uart_circ_empty(xmit))
+               if (!uart_fifo_get(&up->port, &ch))
                        return;
-               writeb(xmit->buf[xmit->tail], &channel->data);
+               writeb(ch, &channel->data);
                ZSDELAY();
                ZS_WSYNC(channel);
 
-               uart_xmit_advance(port, 1);
-
-               if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                        uart_write_wakeup(&up->port);
        }
 }
index d9c78320eb0209085849a00653c8d39997bc343f..21ca5fcadf4997c8fce7e952ba0260755c3dbb41 100644 (file)
@@ -91,15 +91,17 @@ static void tegra_tcu_write(struct tegra_tcu *tcu, const char *s,
 static void tegra_tcu_uart_start_tx(struct uart_port *port)
 {
        struct tegra_tcu *tcu = port->private_data;
-       struct circ_buf *xmit = &port->state->xmit;
-       unsigned long count;
+       struct tty_port *tport = &port->state->port;
+       unsigned char *tail;
+       unsigned int count;
 
        for (;;) {
-               count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+               count = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
+                               UART_XMIT_SIZE);
                if (!count)
                        break;
 
-               tegra_tcu_write(tcu, &xmit->buf[xmit->tail], count);
+               tegra_tcu_write(tcu, tail, count);
                uart_xmit_advance(port, count);
        }
 
index 4bc89a9b380a7509faa4e6e0c58ce4da9b44eb52..43fa0938b5e33e3b544e88564d60583431e2909b 100644 (file)
@@ -95,14 +95,11 @@ static void timbuart_rx_chars(struct uart_port *port)
 
 static void timbuart_tx_chars(struct uart_port *port)
 {
-       struct circ_buf *xmit = &port->state->xmit;
+       unsigned char ch;
 
        while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) &&
-               !uart_circ_empty(xmit)) {
-               iowrite8(xmit->buf[xmit->tail],
-                       port->membase + TIMBUART_TXFIFO);
-               uart_xmit_advance(port, 1);
-       }
+                       uart_fifo_get(port, &ch))
+               iowrite8(ch, port->membase + TIMBUART_TXFIFO);
 
        dev_dbg(port->dev,
                "%s - total written %d bytes, CTL: %x, RTS: %x, baud: %x\n",
@@ -117,9 +114,9 @@ static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier)
 {
        struct timbuart_port *uart =
                container_of(port, struct timbuart_port, port);
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))
                return;
 
        if (port->x_char)
@@ -130,7 +127,7 @@ static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier)
                /* clear all TX interrupts */
                iowrite32(TXFLAGS, port->membase + TIMBUART_ISR);
 
-               if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                        uart_write_wakeup(port);
        } else
                /* Re-enable any tx interrupt */
@@ -141,7 +138,7 @@ static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier)
         * we wake up the upper layer later when we got the interrupt
         * to give it some time to go out...
         */
-       if (!uart_circ_empty(xmit))
+       if (!kfifo_is_empty(&tport->xmit_fifo))
                *ier |= TXBAE;
 
        dev_dbg(port->dev, "%s - leaving\n", __func__);
index 10ba41b7be9944fcc93fc12969b7f06e48abc0da..68357ac8ffe3ca58e1aaba0eb7f509ebb8baeaef 100644 (file)
@@ -189,7 +189,8 @@ static int ulite_receive(struct uart_port *port, int stat)
 
 static int ulite_transmit(struct uart_port *port, int stat)
 {
-       struct circ_buf *xmit  = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
+       unsigned char ch;
 
        if (stat & ULITE_STATUS_TXFULL)
                return 0;
@@ -201,14 +202,16 @@ static int ulite_transmit(struct uart_port *port, int stat)
                return 1;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+       if (uart_tx_stopped(port))
+               return 0;
+
+       if (!uart_fifo_get(port, &ch))
                return 0;
 
-       uart_out32(xmit->buf[xmit->tail], ULITE_TX, port);
-       uart_xmit_advance(port, 1);
+       uart_out32(ch, ULITE_TX, port);
 
        /* wake up */
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        return 1;
index 397b95dff7eda6bc045a40ace5a8b3fa4a408a14..53bb8c5ef499ecd0e3cbfd781a6ca416b9350ea5 100644 (file)
@@ -334,7 +334,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
        unsigned char *p;
        unsigned int count;
        struct uart_port *port = &qe_port->port;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
 
        /* Handle xon/xoff */
        if (port->x_char) {
@@ -358,7 +358,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
                return 1;
        }
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                qe_uart_stop_tx(port);
                return 0;
        }
@@ -366,16 +366,10 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
        /* Pick next descriptor and fill from buffer */
        bdp = qe_port->tx_cur;
 
-       while (!(ioread16be(&bdp->status) & BD_SC_READY) && !uart_circ_empty(xmit)) {
-               count = 0;
+       while (!(ioread16be(&bdp->status) & BD_SC_READY) &&
+              !kfifo_is_empty(&tport->xmit_fifo)) {
                p = qe2cpu_addr(ioread32be(&bdp->buf), qe_port);
-               while (count < qe_port->tx_fifosize) {
-                       *p++ = xmit->buf[xmit->tail];
-                       uart_xmit_advance(port, 1);
-                       count++;
-                       if (uart_circ_empty(xmit))
-                               break;
-               }
+               count = uart_fifo_out(port, p, qe_port->tx_fifosize);
 
                iowrite16be(count, &bdp->length);
                qe_setbits_be16(&bdp->status, BD_SC_READY);
@@ -388,10 +382,10 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
        }
        qe_port->tx_cur = bdp;
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_empty(xmit)) {
+       if (kfifo_is_empty(&tport->xmit_fifo)) {
                /* The kernel buffer is empty, so turn off TX interrupts.  We
                   don't need to be told when the QE is finished transmitting
                   the data. */
index 5f48ec37cb25ff2e9b55950e5a7cfee7d35397bf..de3487206bcb7a4317b5c03825a04fa4a4a1b67b 100644 (file)
@@ -425,32 +425,32 @@ static void cdns_uart_handle_tx(void *dev_id)
 {
        struct uart_port *port = (struct uart_port *)dev_id;
        struct cdns_uart *cdns_uart = port->private_data;
-       struct circ_buf *xmit = &port->state->xmit;
+       struct tty_port *tport = &port->state->port;
        unsigned int numbytes;
+       unsigned char ch;
 
-       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+       if (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
                /* Disable the TX Empty interrupt */
                writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR);
                return;
        }
 
        numbytes = port->fifosize;
-       while (numbytes && !uart_circ_empty(xmit) &&
-              !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL)) {
-
-               writel(xmit->buf[xmit->tail], port->membase + CDNS_UART_FIFO);
-               uart_xmit_advance(port, 1);
+       while (numbytes &&
+              !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL) &&
+              uart_fifo_get(port, &ch)) {
+               writel(ch, port->membase + CDNS_UART_FIFO);
                numbytes--;
        }
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
        /* Enable the TX Empty interrupt */
        writel(CDNS_UART_IXR_TXEMPTY, cdns_uart->port->membase + CDNS_UART_IER);
 
        if (cdns_uart->port->rs485.flags & SER_RS485_ENABLED &&
-           (uart_circ_empty(xmit) || uart_tx_stopped(port))) {
+           (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port))) {
                cdns_uart->tx_timer.function = &cdns_rs485_rx_callback;
                hrtimer_start(&cdns_uart->tx_timer,
                              ns_to_ktime(cdns_calc_after_tx_delay(cdns_uart)), HRTIMER_MODE_REL);
@@ -723,7 +723,7 @@ static void cdns_uart_start_tx(struct uart_port *port)
        status |= CDNS_UART_CR_TX_EN;
        writel(status, port->membase + CDNS_UART_CR);
 
-       if (uart_circ_empty(&port->state->xmit))
+       if (kfifo_is_empty(&port->state->port.xmit_fifo))
                return;
 
        /* Clear the TX Empty interrupt */
index 65ca4da6e368719410f0d4a3bb519380eb94b6de..79ea7108a0f3333f0a2f31362c823900b3ec9132 100644 (file)
@@ -606,7 +606,8 @@ static void zs_receive_chars(struct zs_port *zport)
 
 static void zs_raw_transmit_chars(struct zs_port *zport)
 {
-       struct circ_buf *xmit = &zport->port.state->xmit;
+       struct tty_port *tport = &zport->port.state->port;
+       unsigned char ch;
 
        /* XON/XOFF chars.  */
        if (zport->port.x_char) {
@@ -617,20 +618,20 @@ static void zs_raw_transmit_chars(struct zs_port *zport)
        }
 
        /* If nothing to do or stopped or hardware stopped.  */
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&zport->port)) {
+       if (uart_tx_stopped(&zport->port) ||
+                       !uart_fifo_get(&zport->port, &ch)) {
                zs_raw_stop_tx(zport);
                return;
        }
 
        /* Send char.  */
-       write_zsdata(zport, xmit->buf[xmit->tail]);
-       uart_xmit_advance(&zport->port, 1);
+       write_zsdata(zport, ch);
 
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+       if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
                uart_write_wakeup(&zport->port);
 
        /* Are we are done?  */
-       if (uart_circ_empty(xmit))
+       if (kfifo_is_empty(&tport->xmit_fifo))
                zs_raw_stop_tx(zport);
 }
 
index 0a0f6e21d40ec130e458523947c2caaaf28528cd..8cb65f50e830c8d4ebd46cc5528ec89ce403f66f 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/compiler.h>
 #include <linux/console.h>
 #include <linux/interrupt.h>
-#include <linux/circ_buf.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
@@ -699,7 +698,6 @@ struct uart_state {
        struct tty_port         port;
 
        enum uart_pm_state      pm_state;
-       struct circ_buf         xmit;
 
        atomic_t                refcount;
        wait_queue_head_t       remove_wait;
@@ -723,12 +721,35 @@ struct uart_state {
  */
 static inline void uart_xmit_advance(struct uart_port *up, unsigned int chars)
 {
-       struct circ_buf *xmit = &up->state->xmit;
+       struct tty_port *tport = &up->state->port;
 
-       xmit->tail = (xmit->tail + chars) & (UART_XMIT_SIZE - 1);
+       kfifo_skip_count(&tport->xmit_fifo, chars);
        up->icount.tx += chars;
 }
 
+static inline unsigned int uart_fifo_out(struct uart_port *up,
+               unsigned char *buf, unsigned int chars)
+{
+       struct tty_port *tport = &up->state->port;
+
+       chars = kfifo_out(&tport->xmit_fifo, buf, chars);
+       up->icount.tx += chars;
+
+       return chars;
+}
+
+static inline unsigned int uart_fifo_get(struct uart_port *up,
+               unsigned char *ch)
+{
+       struct tty_port *tport = &up->state->port;
+       unsigned int chars;
+
+       chars = kfifo_get(&tport->xmit_fifo, ch);
+       up->icount.tx += chars;
+
+       return chars;
+}
+
 struct module;
 struct tty_driver;
 
@@ -764,7 +785,7 @@ enum UART_TX_FLAGS {
                       for_test, for_post)                                    \
 ({                                                                           \
        struct uart_port *__port = (uport);                                   \
-       struct circ_buf *xmit = &__port->state->xmit;                         \
+       struct tty_port *__tport = &__port->state->port;                      \
        unsigned int pending;                                                 \
                                                                              \
        for (; (for_test) && (tx_ready); (for_post), __port->icount.tx++) {   \
@@ -775,17 +796,18 @@ enum UART_TX_FLAGS {
                        continue;                                             \
                }                                                             \
                                                                              \
-               if (uart_circ_empty(xmit) || uart_tx_stopped(__port))         \
+               if (uart_tx_stopped(__port))                                  \
+                       break;                                                \
+                                                                             \
+               if (!kfifo_get(&__tport->xmit_fifo, &(ch)))                   \
                        break;                                                \
                                                                              \
-               (ch) = xmit->buf[xmit->tail];                                 \
                (put_char);                                                   \
-               xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE;               \
        }                                                                     \
                                                                              \
        (tx_done);                                                            \
                                                                              \
-       pending = uart_circ_chars_pending(xmit);                              \
+       pending = kfifo_len(&__tport->xmit_fifo);                             \
        if (pending < WAKEUP_CHARS) {                                         \
                uart_write_wakeup(__port);                                    \
                                                                              \
@@ -974,15 +996,6 @@ bool uart_match_port(const struct uart_port *port1,
 int uart_suspend_port(struct uart_driver *reg, struct uart_port *port);
 int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
 
-#define uart_circ_empty(circ)          ((circ)->head == (circ)->tail)
-#define uart_circ_clear(circ)          ((circ)->head = (circ)->tail = 0)
-
-#define uart_circ_chars_pending(circ)  \
-       (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
-
-#define uart_circ_chars_free(circ)     \
-       (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
-
 static inline int uart_tx_stopped(struct uart_port *port)
 {
        struct tty_struct *tty = port->state->port.tty;
This page took 0.265523 seconds and 4 git commands to generate.