[PATCH v2 2/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA tx support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add SCIF DMA tx support for RZ/G2L alike SoCs.

RZ/G2L alike SoC use the same signal for both interrupt and DMA
transfer requests, so we must disable line interrupts(tx and tx end)
while transferring DMA and enable the TIE source interrupt.

Based on a patch in the BSP by Long Luu
<long.luu.ur@xxxxxxxxxxx>

Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
v1->v2:
 * No change
---
 drivers/tty/serial/sh-sci.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 4278aef59f6d..81797eb722cb 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -172,6 +172,13 @@ to_sci_port(struct uart_port *uart)
 	return container_of(uart, struct sci_port, port);
 }
 
+static inline bool is_rz_scif_port(struct uart_port *port, struct sci_port *s)
+{
+	const struct plat_sci_port *p = s->cfg;
+
+	return port->type == PORT_SCIF && p->regtype == SCIx_RZ_SCIFA_REGTYPE;
+}
+
 static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
 	/*
 	 * Common SCI definitions, dependent on the port's regshift
@@ -588,6 +595,16 @@ 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 (is_rz_scif_port(port, s)) {
+			/* Switch irq from SCIF to DMA */
+			disable_irq(s->irqs[SCIx_TXI_IRQ]);
+			disable_irq(s->irqs[SCIx_TEI_IRQ]);
+
+			/* DMA need TIE enable */
+			ctrl = serial_port_in(port, SCSCR);
+			serial_port_out(port, SCSCR, ctrl | SCSCR_TIE);
+		}
+
 		s->cookie_tx = 0;
 		schedule_work(&s->work_tx);
 	}
@@ -1214,9 +1231,16 @@ 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 ||
+		    is_rz_scif_port(port, s)) {
 			u16 ctrl = serial_port_in(port, SCSCR);
 			serial_port_out(port, SCSCR, ctrl & ~SCSCR_TIE);
+			if (port->type == PORT_SCIF) {
+				/* Switch irq from DMA to SCIF */
+				dmaengine_pause(s->chan_tx_saved);
+				enable_irq(s->irqs[SCIx_TXI_IRQ]);
+				enable_irq(s->irqs[SCIx_TEI_IRQ]);
+			}
 		}
 	}
 
-- 
2.25.1




[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux