Commit cf383d12 authored by Biju Das's avatar Biju Das Committed by Greg Kroah-Hartman
Browse files

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: default avatarBiju 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: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8749061b
Loading
Loading
Loading
Loading
+19 −7
Original line number Diff line number Diff line
@@ -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);
		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;