Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * 8250_dma.c - DMA Engine API support for 8250.c
0004  *
0005  * Copyright (C) 2013 Intel Corporation
0006  */
0007 #include <linux/tty.h>
0008 #include <linux/tty_flip.h>
0009 #include <linux/serial_reg.h>
0010 #include <linux/dma-mapping.h>
0011 
0012 #include "8250.h"
0013 
0014 static void __dma_tx_complete(void *param)
0015 {
0016     struct uart_8250_port   *p = param;
0017     struct uart_8250_dma    *dma = p->dma;
0018     struct circ_buf     *xmit = &p->port.state->xmit;
0019     unsigned long   flags;
0020     int     ret;
0021 
0022     dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr,
0023                 UART_XMIT_SIZE, DMA_TO_DEVICE);
0024 
0025     spin_lock_irqsave(&p->port.lock, flags);
0026 
0027     dma->tx_running = 0;
0028 
0029     xmit->tail += dma->tx_size;
0030     xmit->tail &= UART_XMIT_SIZE - 1;
0031     p->port.icount.tx += dma->tx_size;
0032 
0033     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0034         uart_write_wakeup(&p->port);
0035 
0036     ret = serial8250_tx_dma(p);
0037     if (ret || !dma->tx_running)
0038         serial8250_set_THRI(p);
0039 
0040     spin_unlock_irqrestore(&p->port.lock, flags);
0041 }
0042 
0043 static void __dma_rx_complete(void *param)
0044 {
0045     struct uart_8250_port   *p = param;
0046     struct uart_8250_dma    *dma = p->dma;
0047     struct tty_port     *tty_port = &p->port.state->port;
0048     struct dma_tx_state state;
0049     int         count;
0050 
0051     dma->rx_running = 0;
0052     dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
0053 
0054     count = dma->rx_size - state.residue;
0055 
0056     tty_insert_flip_string(tty_port, dma->rx_buf, count);
0057     p->port.icount.rx += count;
0058 
0059     tty_flip_buffer_push(tty_port);
0060 }
0061 
0062 int serial8250_tx_dma(struct uart_8250_port *p)
0063 {
0064     struct uart_8250_dma        *dma = p->dma;
0065     struct circ_buf         *xmit = &p->port.state->xmit;
0066     struct dma_async_tx_descriptor  *desc;
0067     struct uart_port        *up = &p->port;
0068     int ret;
0069 
0070     if (dma->tx_running) {
0071         if (up->x_char) {
0072             dmaengine_pause(dma->txchan);
0073             uart_xchar_out(up, UART_TX);
0074             dmaengine_resume(dma->txchan);
0075         }
0076         return 0;
0077     } else if (up->x_char) {
0078         uart_xchar_out(up, UART_TX);
0079     }
0080 
0081     if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) {
0082         /* We have been called from __dma_tx_complete() */
0083         return 0;
0084     }
0085 
0086     dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
0087 
0088     serial8250_do_prepare_tx_dma(p);
0089 
0090     desc = dmaengine_prep_slave_single(dma->txchan,
0091                        dma->tx_addr + xmit->tail,
0092                        dma->tx_size, DMA_MEM_TO_DEV,
0093                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
0094     if (!desc) {
0095         ret = -EBUSY;
0096         goto err;
0097     }
0098 
0099     dma->tx_running = 1;
0100     desc->callback = __dma_tx_complete;
0101     desc->callback_param = p;
0102 
0103     dma->tx_cookie = dmaengine_submit(desc);
0104 
0105     dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr,
0106                    UART_XMIT_SIZE, DMA_TO_DEVICE);
0107 
0108     dma_async_issue_pending(dma->txchan);
0109     serial8250_clear_THRI(p);
0110     if (dma->tx_err)
0111         dma->tx_err = 0;
0112 
0113     return 0;
0114 err:
0115     dma->tx_err = 1;
0116     return ret;
0117 }
0118 
0119 int serial8250_rx_dma(struct uart_8250_port *p)
0120 {
0121     struct uart_8250_dma        *dma = p->dma;
0122     struct dma_async_tx_descriptor  *desc;
0123 
0124     if (dma->rx_running)
0125         return 0;
0126 
0127     serial8250_do_prepare_rx_dma(p);
0128 
0129     desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
0130                        dma->rx_size, DMA_DEV_TO_MEM,
0131                        DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
0132     if (!desc)
0133         return -EBUSY;
0134 
0135     dma->rx_running = 1;
0136     desc->callback = __dma_rx_complete;
0137     desc->callback_param = p;
0138 
0139     dma->rx_cookie = dmaengine_submit(desc);
0140 
0141     dma_async_issue_pending(dma->rxchan);
0142 
0143     return 0;
0144 }
0145 
0146 void serial8250_rx_dma_flush(struct uart_8250_port *p)
0147 {
0148     struct uart_8250_dma *dma = p->dma;
0149 
0150     if (dma->rx_running) {
0151         dmaengine_pause(dma->rxchan);
0152         __dma_rx_complete(p);
0153         dmaengine_terminate_async(dma->rxchan);
0154     }
0155 }
0156 EXPORT_SYMBOL_GPL(serial8250_rx_dma_flush);
0157 
0158 int serial8250_request_dma(struct uart_8250_port *p)
0159 {
0160     struct uart_8250_dma    *dma = p->dma;
0161     phys_addr_t rx_dma_addr = dma->rx_dma_addr ?
0162                   dma->rx_dma_addr : p->port.mapbase;
0163     phys_addr_t tx_dma_addr = dma->tx_dma_addr ?
0164                   dma->tx_dma_addr : p->port.mapbase;
0165     dma_cap_mask_t      mask;
0166     struct dma_slave_caps   caps;
0167     int         ret;
0168 
0169     /* Default slave configuration parameters */
0170     dma->rxconf.direction       = DMA_DEV_TO_MEM;
0171     dma->rxconf.src_addr_width  = DMA_SLAVE_BUSWIDTH_1_BYTE;
0172     dma->rxconf.src_addr        = rx_dma_addr + UART_RX;
0173 
0174     dma->txconf.direction       = DMA_MEM_TO_DEV;
0175     dma->txconf.dst_addr_width  = DMA_SLAVE_BUSWIDTH_1_BYTE;
0176     dma->txconf.dst_addr        = tx_dma_addr + UART_TX;
0177 
0178     dma_cap_zero(mask);
0179     dma_cap_set(DMA_SLAVE, mask);
0180 
0181     /* Get a channel for RX */
0182     dma->rxchan = dma_request_slave_channel_compat(mask,
0183                                dma->fn, dma->rx_param,
0184                                p->port.dev, "rx");
0185     if (!dma->rxchan)
0186         return -ENODEV;
0187 
0188     /* 8250 rx dma requires dmaengine driver to support pause/terminate */
0189     ret = dma_get_slave_caps(dma->rxchan, &caps);
0190     if (ret)
0191         goto release_rx;
0192     if (!caps.cmd_pause || !caps.cmd_terminate ||
0193         caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR) {
0194         ret = -EINVAL;
0195         goto release_rx;
0196     }
0197 
0198     dmaengine_slave_config(dma->rxchan, &dma->rxconf);
0199 
0200     /* Get a channel for TX */
0201     dma->txchan = dma_request_slave_channel_compat(mask,
0202                                dma->fn, dma->tx_param,
0203                                p->port.dev, "tx");
0204     if (!dma->txchan) {
0205         ret = -ENODEV;
0206         goto release_rx;
0207     }
0208 
0209     /* 8250 tx dma requires dmaengine driver to support terminate */
0210     ret = dma_get_slave_caps(dma->txchan, &caps);
0211     if (ret)
0212         goto err;
0213     if (!caps.cmd_terminate) {
0214         ret = -EINVAL;
0215         goto err;
0216     }
0217 
0218     dmaengine_slave_config(dma->txchan, &dma->txconf);
0219 
0220     /* RX buffer */
0221     if (!dma->rx_size)
0222         dma->rx_size = PAGE_SIZE;
0223 
0224     dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size,
0225                     &dma->rx_addr, GFP_KERNEL);
0226     if (!dma->rx_buf) {
0227         ret = -ENOMEM;
0228         goto err;
0229     }
0230 
0231     /* TX buffer */
0232     dma->tx_addr = dma_map_single(dma->txchan->device->dev,
0233                     p->port.state->xmit.buf,
0234                     UART_XMIT_SIZE,
0235                     DMA_TO_DEVICE);
0236     if (dma_mapping_error(dma->txchan->device->dev, dma->tx_addr)) {
0237         dma_free_coherent(dma->rxchan->device->dev, dma->rx_size,
0238                   dma->rx_buf, dma->rx_addr);
0239         ret = -ENOMEM;
0240         goto err;
0241     }
0242 
0243     dev_dbg_ratelimited(p->port.dev, "got both dma channels\n");
0244 
0245     return 0;
0246 err:
0247     dma_release_channel(dma->txchan);
0248 release_rx:
0249     dma_release_channel(dma->rxchan);
0250     return ret;
0251 }
0252 EXPORT_SYMBOL_GPL(serial8250_request_dma);
0253 
0254 void serial8250_release_dma(struct uart_8250_port *p)
0255 {
0256     struct uart_8250_dma *dma = p->dma;
0257 
0258     if (!dma)
0259         return;
0260 
0261     /* Release RX resources */
0262     dmaengine_terminate_sync(dma->rxchan);
0263     dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, dma->rx_buf,
0264               dma->rx_addr);
0265     dma_release_channel(dma->rxchan);
0266     dma->rxchan = NULL;
0267 
0268     /* Release TX resources */
0269     dmaengine_terminate_sync(dma->txchan);
0270     dma_unmap_single(dma->txchan->device->dev, dma->tx_addr,
0271              UART_XMIT_SIZE, DMA_TO_DEVICE);
0272     dma_release_channel(dma->txchan);
0273     dma->txchan = NULL;
0274     dma->tx_running = 0;
0275 
0276     dev_dbg_ratelimited(p->port.dev, "dma channels released\n");
0277 }
0278 EXPORT_SYMBOL_GPL(serial8250_release_dma);