On Wed, Mar 30, 2022 at 03:20:34PM +0200, Miquel Raynal wrote: > 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. OK! Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > Suggested-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> > --- > drivers/tty/serial/8250/8250.h | 18 ++++++++++++++++++ > drivers/tty/serial/8250/8250_dma.c | 4 ++++ > 2 files changed, 22 insertions(+) > > diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h > index db784ace25d8..d19f24e4d13e 100644 > --- a/drivers/tty/serial/8250/8250.h > +++ b/drivers/tty/serial/8250/8250.h > @@ -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; > @@ -301,6 +303,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) > { > diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c > index 890fa7ddaa7f..558d3a2ac65b 100644 > --- a/drivers/tty/serial/8250/8250_dma.c > +++ b/drivers/tty/serial/8250/8250_dma.c > @@ -77,6 +77,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, > @@ -114,6 +116,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); > -- > 2.27.0 > -- With Best Regards, Andy Shevchenko