serial: sh-sci: modify sci_break_ctl()

SCIF modules which have SCSPTR can output the break signal. Now that we
have a way of determining port features/capabilities, add trivial break
control via SCSPTR support. Tested on sh7757lcr.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 3158e17..3e471fc 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1564,10 +1564,32 @@
 
 static void sci_break_ctl(struct uart_port *port, int break_state)
 {
-	/*
-	 * Not supported by hardware. Most parts couple break and rx
-	 * interrupts together, with break detection always enabled.
-	 */
+	struct sci_port *s = to_sci_port(port);
+	unsigned short scscr, scsptr;
+
+	switch (s->cfg->regtype) {
+	case SCIx_SH4_SCIF_REGTYPE:
+		scsptr = serial_port_in(port, SCSPTR);
+		scscr = serial_port_in(port, SCSCR);
+
+		if (break_state == -1) {
+			scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT;
+			scscr &= ~SCSCR_TE;
+		} else {
+			scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO;
+			scscr |= SCSCR_TE;
+		}
+
+		serial_port_out(port, SCSPTR, scsptr);
+		serial_port_out(port, SCSCR, scscr);
+		break;
+	default:
+		/*
+		 * Not supported by hardware. Most parts couple break and rx
+		 * interrupts together, with break detection always enabled.
+		 */
+		break;
+	}
 }
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index 7877907..eb763adf 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -52,6 +52,8 @@
 /* SCSPTR, optional */
 #define SCSPTR_RTSIO	(1 << 7)
 #define SCSPTR_CTSIO	(1 << 5)
+#define SCSPTR_SPB2IO	(1 << 1)
+#define SCSPTR_SPB2DT	(1 << 0)
 
 /* Offsets into the sci_port->irqs array */
 enum {