From ff11d0780376a3821d790a6ceb8b297d976b14fe Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 7 Feb 2008 00:15:14 -0800 Subject: [PATCH] dz: clean up and improve the setup of termios settings A set of changes to the way termios settings are propagated to the serial port hardware. The DZ11 only supports a selection of fixed baud settings, so some requests may not be fulfilled. Keep the old setting in such a case and failing that resort to 9600bps. Also add a missing update of the transmit timeout. And remove the explicit encoding of the line selected from writes to the Line Parameters Register as it has been preencoded by the ->set_termios() call already. Finally, remove a duplicate macro for the Receiver Enable bit. Signed-off-by: Maciej W. Rozycki Cc: Ralf Baechle Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/dz.c | 103 +++++++++++++++++++++++--------------------- drivers/serial/dz.h | 4 +- 2 files changed, 56 insertions(+), 51 deletions(-) diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index ae3203b2013..765b700c019 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c @@ -128,8 +128,8 @@ static void dz_stop_rx(struct uart_port *uport) { struct dz_port *dport = (struct dz_port *)uport; - dport->cflag &= ~DZ_CREAD; - dz_out(dport, DZ_LPR, dport->cflag | dport->port.line); + dport->cflag &= ~DZ_RXENAB; + dz_out(dport, DZ_LPR, dport->cflag); } static void dz_enable_ms(struct uart_port *port) @@ -464,12 +464,51 @@ static void dz_break_ctl(struct uart_port *uport, int break_state) spin_unlock_irqrestore(&uport->lock, flags); } +static int dz_encode_baud_rate(unsigned int baud) +{ + switch (baud) { + case 50: + return DZ_B50; + case 75: + return DZ_B75; + case 110: + return DZ_B110; + case 134: + return DZ_B134; + case 150: + return DZ_B150; + case 300: + return DZ_B300; + case 600: + return DZ_B600; + case 1200: + return DZ_B1200; + case 1800: + return DZ_B1800; + case 2000: + return DZ_B2000; + case 2400: + return DZ_B2400; + case 3600: + return DZ_B3600; + case 4800: + return DZ_B4800; + case 7200: + return DZ_B7200; + case 9600: + return DZ_B9600; + default: + return -1; + } +} + static void dz_set_termios(struct uart_port *uport, struct ktermios *termios, struct ktermios *old_termios) { struct dz_port *dport = (struct dz_port *)uport; unsigned long flags; unsigned int cflag, baud; + int bflag; cflag = dport->port.line; @@ -496,60 +535,26 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios, cflag |= DZ_PARODD; baud = uart_get_baud_rate(uport, termios, old_termios, 50, 9600); - switch (baud) { - case 50: - cflag |= DZ_B50; - break; - case 75: - cflag |= DZ_B75; - break; - case 110: - cflag |= DZ_B110; - break; - case 134: - cflag |= DZ_B134; - break; - case 150: - cflag |= DZ_B150; - break; - case 300: - cflag |= DZ_B300; - break; - case 600: - cflag |= DZ_B600; - break; - case 1200: - cflag |= DZ_B1200; - break; - case 1800: - cflag |= DZ_B1800; - break; - case 2000: - cflag |= DZ_B2000; - break; - case 2400: - cflag |= DZ_B2400; - break; - case 3600: - cflag |= DZ_B3600; - break; - case 4800: - cflag |= DZ_B4800; - break; - case 7200: - cflag |= DZ_B7200; - break; - case 9600: - default: - cflag |= DZ_B9600; + bflag = dz_encode_baud_rate(baud); + if (bflag < 0) { /* Try to keep unchanged. */ + baud = uart_get_baud_rate(uport, old_termios, NULL, 50, 9600); + bflag = dz_encode_baud_rate(baud); + if (bflag < 0) { /* Resort to 9600. */ + baud = 9600; + bflag = DZ_B9600; + } + tty_termios_encode_baud_rate(termios, baud, baud); } + cflag |= bflag; if (termios->c_cflag & CREAD) cflag |= DZ_RXENAB; spin_lock_irqsave(&dport->port.lock, flags); - dz_out(dport, DZ_LPR, cflag | dport->port.line); + uart_update_timeout(uport, termios->c_cflag, baud); + + dz_out(dport, DZ_LPR, cflag); dport->cflag = cflag; /* setup accept flag */ diff --git a/drivers/serial/dz.h b/drivers/serial/dz.h index 1e836c3411d..faf169ed27b 100644 --- a/drivers/serial/dz.h +++ b/drivers/serial/dz.h @@ -109,8 +109,8 @@ #define DZ_B7200 0x0D00 #define DZ_B9600 0x0E00 -#define DZ_CREAD 0x1000 /* Enable receiver */ -#define DZ_RXENAB 0x1000 /* enable receive char */ +#define DZ_RXENAB 0x1000 /* Receiver Enable */ + /* * Addresses for the DZ registers */