serial: 8250: dma: Allow driver operations before starting DMA transfers
[ Upstream commit e4fb03fe10c5e7a5d9aef7cefe815253274fb9ee ] One situation where this could be used is when configuring the UART controller to be the DMA flow controller. This is a typical case where the driver might need to program a few more registers before starting a DMA transfer. Provide the necessary infrastructure to support this case. Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/r/20220422180615.9098-6-miquel.raynal@bootlin.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
f945b12e65
commit
ad7fd9f652
@ -17,6 +17,8 @@
|
||||
struct uart_8250_dma {
|
||||
int (*tx_dma)(struct uart_8250_port *p);
|
||||
int (*rx_dma)(struct uart_8250_port *p);
|
||||
void (*prepare_tx_dma)(struct uart_8250_port *p);
|
||||
void (*prepare_rx_dma)(struct uart_8250_port *p);
|
||||
|
||||
/* Filter function */
|
||||
dma_filter_fn fn;
|
||||
@ -331,6 +333,22 @@ extern int serial8250_rx_dma(struct uart_8250_port *);
|
||||
extern void serial8250_rx_dma_flush(struct uart_8250_port *);
|
||||
extern int serial8250_request_dma(struct uart_8250_port *);
|
||||
extern void serial8250_release_dma(struct uart_8250_port *);
|
||||
|
||||
static inline void serial8250_do_prepare_tx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
|
||||
if (dma->prepare_tx_dma)
|
||||
dma->prepare_tx_dma(p);
|
||||
}
|
||||
|
||||
static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
struct uart_8250_dma *dma = p->dma;
|
||||
|
||||
if (dma->prepare_rx_dma)
|
||||
dma->prepare_rx_dma(p);
|
||||
}
|
||||
#else
|
||||
static inline int serial8250_tx_dma(struct uart_8250_port *p)
|
||||
{
|
||||
|
@ -86,6 +86,8 @@ int serial8250_tx_dma(struct uart_8250_port *p)
|
||||
|
||||
dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
|
||||
|
||||
serial8250_do_prepare_tx_dma(p);
|
||||
|
||||
desc = dmaengine_prep_slave_single(dma->txchan,
|
||||
dma->tx_addr + xmit->tail,
|
||||
dma->tx_size, DMA_MEM_TO_DEV,
|
||||
@ -123,6 +125,8 @@ int serial8250_rx_dma(struct uart_8250_port *p)
|
||||
if (dma->rx_running)
|
||||
return 0;
|
||||
|
||||
serial8250_do_prepare_rx_dma(p);
|
||||
|
||||
desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
|
||||
dma->rx_size, DMA_DEV_TO_MEM,
|
||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
|
Loading…
x
Reference in New Issue
Block a user