Thread (18 messages) 18 messages, 4 authors, 2021-08-09
STALE1757d

[PATCH 5/5] tty: serial: uartlite: Prevent changing fixed parameters

From: Sean Anderson <hidden>
Date: 2021-07-23 22:32:20
Subsystem: the rest, tty layer and serial drivers, xilinx uartlite serial driver · Maintainers: Linus Torvalds, Greg Kroah-Hartman, Jiri Slaby, Peter Korsgaard

This device does not support changing baud, parity, data bits, stop
bits, or detecting breaks. Disable "changing" these settings to prevent
their termios from diverging from the actual state of the uart. To inform
users of these limitations, warn if the new termios change these
parameters. We only do this once to avoid spamming the log. These
warnings are inspired by those in the sifive driver.

Signed-off-by: Sean Anderson <redacted>
---

 drivers/tty/serial/uartlite.c | 52 +++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c
index 39c17ab206ca..0aed70039f46 100644
--- a/drivers/tty/serial/uartlite.c
+++ b/drivers/tty/serial/uartlite.c
@@ -314,7 +314,54 @@ static void ulite_set_termios(struct uart_port *port, struct ktermios *termios,
 			      struct ktermios *old)
 {
 	unsigned long flags;
-	unsigned int baud;
+	struct uartlite_data *pdata = port->private_data;
+	tcflag_t old_cflag;
+
+	if (termios->c_iflag & BRKINT)
+		dev_err_once(port->dev, "BREAK detection not supported\n");
+	termios->c_iflag &= ~BRKINT;
+
+	if (termios->c_cflag & CSTOPB)
+		dev_err_once(port->dev, "only one stop bit supported\n");
+	termios->c_cflag &= ~CSTOPB;
+
+	old_cflag = termios->c_cflag;
+	termios->c_cflag &= ~(PARENB | PARODD);
+	if (pdata->parity == 'e')
+		termios->c_cflag |= PARENB;
+	else if (pdata->parity == 'o')
+		termios->c_cflag |= PARENB | PARODD;
+
+	if (termios->c_cflag != old_cflag)
+		dev_err_once(port->dev, "only '%c' parity supported\n",
+			     pdata->parity);
+
+	old_cflag = termios->c_cflag;
+	termios->c_cflag &= ~CSIZE;
+	switch (termios->c_cflag & CSIZE) {
+	case 5:
+		termios->c_cflag |= CS5;
+		break;
+	case 6:
+		termios->c_cflag |= CS6;
+		break;
+	case 7:
+		termios->c_cflag |= CS7;
+		break;
+	default:
+	case 8:
+		termios->c_cflag |= CS8;
+		break;
+	}
+	if (termios->c_cflag != old_cflag)
+		dev_err_once(port->dev, "only %d data bits supported\n",
+			     pdata->bits);
+
+	old_cflag = termios->c_cflag;
+	tty_termios_encode_baud_rate(termios, pdata->baud, pdata->baud);
+	if (termios->c_cflag != old_cflag)
+		dev_err_once(port->dev, "only %d baud supported\n",
+			     pdata->baud);
 
 	spin_lock_irqsave(&port->lock, flags);
 
@@ -337,8 +384,7 @@ static void ulite_set_termios(struct uart_port *port, struct ktermios *termios,
 			| ULITE_STATUS_FRAME | ULITE_STATUS_OVERRUN;
 
 	/* update timeout */
-	baud = uart_get_baud_rate(port, termios, old, 0, 460800);
-	uart_update_timeout(port, termios->c_cflag, baud);
+	uart_update_timeout(port, termios->c_cflag, pdata->baud);
 
 	spin_unlock_irqrestore(&port->lock, flags);
 }
-- 
2.25.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help