tty: serial: sh-sci: Add RZ/G2L SCIFA DMA rx 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 rx support for RZ/G2L alike SoCs by disabling RXI line
interrupt and setting DMARS registers by DMA api for DMA transfer request.

Apart from this, we must set FIFO trigger to 1 for the expected behavior
of the receive transmission.

While at it replace the parameter irq to s->irqs[SCIx_RXI_IRQ] in
disable_irq_nosync() to match enable_irq() in sci_dma_rx_reenable_irq().

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20230412145053.114847-3-biju.das.jz@bp.renesas.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Biju Das 2023-04-12 15:50:50 +01:00 committed by Greg Kroah-Hartman
parent 8749061be1
commit cf383d1238

View File

@ -1277,9 +1277,13 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s)
/* Direct new serial port interrupts back to CPU */
scr = serial_port_in(port, SCSCR);
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
scr &= ~SCSCR_RDRQE;
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
enable_irq(s->irqs[SCIx_RXI_IRQ]);
if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
scif_set_rtrg(port, s->rx_trigger);
else
scr &= ~SCSCR_RDRQE;
}
serial_port_out(port, SCSCR, scr | SCSCR_RIE);
}
@ -1516,7 +1520,8 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t)
tty_flip_buffer_push(&port->state->port);
}
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)
sci_dma_rx_submit(s, true);
sci_dma_rx_reenable_irq(s);
@ -1640,7 +1645,8 @@ static void sci_request_dma(struct uart_port *port)
s->chan_rx_saved = s->chan_rx = chan;
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)
sci_dma_rx_submit(s, false);
}
}
@ -1693,9 +1699,15 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
u16 ssr = serial_port_in(port, SCxSR);
/* Disable future Rx interrupts */
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
disable_irq_nosync(irq);
scr |= SCSCR_RDRQE;
if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
scif_set_rtrg(port, 1);
scr |= SCSCR_RIE;
} else {
scr |= SCSCR_RDRQE;
}
} else {
if (sci_dma_rx_submit(s, false) < 0)
goto handle_pio;