Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tty: serial: sh-sci: Add support for tx end interrupt handling

As per the RZ/G2L users hardware manual (Rev.1.20 Sep, 2022), section
23.3.7 Serial Data Transmission (Asynchronous Mode), it is mentioned
that, set the SCR.TIE bit to 0 and SCR.TEIE bit to 1, after the last
data to be transmitted are written to the TDR.

This will generate tx end interrupt and in the handler set SCR.TE and
SCR.TEIE to 0.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20230412145053.114847-5-biju.das.jz@bp.renesas.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Biju Das and committed by
Greg Kroah-Hartman
d61ae331 1707ce2d

+31 -3
+28 -3
drivers/tty/serial/sh-sci.c
··· 860 860 861 861 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 862 862 uart_write_wakeup(port); 863 - if (uart_circ_empty(xmit)) 864 - sci_stop_tx(port); 863 + if (uart_circ_empty(xmit)) { 864 + if (port->type == PORT_SCI) { 865 + ctrl = serial_port_in(port, SCSCR); 866 + ctrl &= ~SCSCR_TIE; 867 + ctrl |= SCSCR_TEIE; 868 + serial_port_out(port, SCSCR, ctrl); 869 + } 865 870 871 + sci_stop_tx(port); 872 + } 866 873 } 867 874 868 875 static void sci_receive_chars(struct uart_port *port) ··· 1773 1766 return IRQ_HANDLED; 1774 1767 } 1775 1768 1769 + static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr) 1770 + { 1771 + struct uart_port *port = ptr; 1772 + unsigned long flags; 1773 + unsigned short ctrl; 1774 + 1775 + if (port->type != PORT_SCI) 1776 + return sci_tx_interrupt(irq, ptr); 1777 + 1778 + spin_lock_irqsave(&port->lock, flags); 1779 + ctrl = serial_port_in(port, SCSCR); 1780 + ctrl &= ~(SCSCR_TE | SCSCR_TEIE); 1781 + serial_port_out(port, SCSCR, ctrl); 1782 + spin_unlock_irqrestore(&port->lock, flags); 1783 + 1784 + return IRQ_HANDLED; 1785 + } 1786 + 1776 1787 static irqreturn_t sci_br_interrupt(int irq, void *ptr) 1777 1788 { 1778 1789 struct uart_port *port = ptr; ··· 1927 1902 1928 1903 [SCIx_TEI_IRQ] = { 1929 1904 .desc = "tx end", 1930 - .handler = sci_tx_interrupt, 1905 + .handler = sci_tx_end_interrupt, 1931 1906 }, 1932 1907 1933 1908 /*
+3
drivers/tty/serial/sh-sci.h
··· 59 59 #define SCSMR_SRC_19 0x0600 /* Sampling rate 1/19 */ 60 60 #define SCSMR_SRC_27 0x0700 /* Sampling rate 1/27 */ 61 61 62 + /* Serial Control Register, SCI only bits */ 63 + #define SCSCR_TEIE BIT(2) /* Transmit End Interrupt Enable */ 64 + 62 65 /* Serial Control Register, SCIFA/SCIFB only bits */ 63 66 #define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */ 64 67 #define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */