summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorBiju Das <biju.das.jz@bp.renesas.com>2023-04-12 15:50:49 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-04-20 13:47:33 +0200
commit8749061be196b41a874d71c073c03171bf2741b2 (patch)
treebd494c04fbcbfc49d0c5beeac31040dbecd844ff /drivers/tty
parent3f42b142ea1171967e40e10e4b0241c0d6d28d41 (diff)
tty: serial: sh-sci: Add RZ/G2L SCIFA DMA tx support
SCIFA IP on RZ/G2L SoC has the same signal for both interrupt and DMA transfer request. Setting DMARS register for DMA transfer makes the signal to work as a DMA transfer request signal and subsequent interrupt requests to the interrupt controller are masked. Similarly clearing DMARS register makes signal to work as interrupt signal and subsequent interrupt requests to the interrupt controller are unmasked. Add SCIFA DMA tx support for RZ/G2L alike SoCs by disabling TXI line interrupt and setting DMARS registers by DMA api for DMA transfer request. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Link: https://lore.kernel.org/r/20230412145053.114847-2-biju.das.jz@bp.renesas.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/sh-sci.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ca31e34afd83..f70d06a03864 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -588,12 +588,17 @@ static void sci_start_tx(struct uart_port *port)
if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
dma_submit_error(s->cookie_tx)) {
+ if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
+ /* Switch irq from SCIF to DMA */
+ disable_irq(s->irqs[SCIx_TXI_IRQ]);
+
s->cookie_tx = 0;
schedule_work(&s->work_tx);
}
#endif
- if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ if (!s->chan_tx || s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE ||
+ port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = serial_port_in(port, SCSCR);
serial_port_out(port, SCSCR, ctrl | SCSCR_TIE);
@@ -1192,9 +1197,15 @@ static void sci_dma_tx_complete(void *arg)
schedule_work(&s->work_tx);
} else {
s->cookie_tx = -EINVAL;
- if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
+ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+ s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
u16 ctrl = serial_port_in(port, SCSCR);
serial_port_out(port, SCSCR, ctrl & ~SCSCR_TIE);
+ if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+ /* Switch irq from DMA to SCIF */
+ dmaengine_pause(s->chan_tx_saved);
+ enable_irq(s->irqs[SCIx_TXI_IRQ]);
+ }
}
}