@@ -855,9 +855,16 @@ static void sci_transmit_chars(struct uart_port *port)
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
- if (uart_circ_empty(xmit))
- sci_stop_tx(port);
+ if (uart_circ_empty(xmit)) {
+ if (port->type == PORT_SCI) {
+ ctrl = serial_port_in(port, SCSCR);
+ ctrl &= ~SCSCR_TIE;
+ ctrl |= SCSCR_TEIE;
+ serial_port_out(port, SCSCR, ctrl);
+ }
+ sci_stop_tx(port);
+ }
}
/* On SH3, SCIF may read end-of-break as a space->mark char */
@@ -1766,6 +1773,24 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
return IRQ_HANDLED;
}
+static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
+{
+ struct uart_port *port = ptr;
+ unsigned long flags;
+ unsigned short ctrl;
+
+ if (port->type != PORT_SCI)
+ return sci_tx_interrupt(irq, ptr);
+
+ spin_lock_irqsave(&port->lock, flags);
+ ctrl = serial_port_in(port, SCSCR);
+ ctrl &= ~(SCSCR_TE | SCSCR_TEIE);
+ serial_port_out(port, SCSCR, ctrl);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
static irqreturn_t sci_br_interrupt(int irq, void *ptr)
{
struct uart_port *port = ptr;
@@ -1902,7 +1927,7 @@ static const struct sci_irq_desc {
[SCIx_TEI_IRQ] = {
.desc = "tx end",
- .handler = sci_tx_interrupt,
+ .handler = sci_tx_end_interrupt,
},
/*
@@ -59,6 +59,9 @@ enum {
#define SCSMR_SRC_19 0x0600 /* Sampling rate 1/19 */
#define SCSMR_SRC_27 0x0700 /* Sampling rate 1/27 */
+/* Serial Control Register, SCI only bits */
+#define SCSCR_TEIE BIT(2) /* Transmit End Interrupt Enable */
+
/* Serial Control Register, SCIFA/SCIFB only bits */
#define SCSCR_TDRQE BIT(15) /* Tx Data Transfer Request Enable */
#define SCSCR_RDRQE BIT(14) /* Rx Data Transfer Request Enable */