Commit 512c5637 authored by Russell King's avatar Russell King

[SERIAL] Move quot/divisor calculation to uart_get_divisor()

uart_get_divisor() calculates the divisor for standard uarts, and
will eventually become a helper function for low level port drivers.
parent b1a5ffda
...@@ -301,14 +301,14 @@ uart_get_baud_rate(struct uart_port *port, struct tty_struct *tty) ...@@ -301,14 +301,14 @@ uart_get_baud_rate(struct uart_port *port, struct tty_struct *tty)
} }
static inline static inline
unsigned int uart_calculate_quot(struct uart_info *info, unsigned int baud) unsigned int uart_calculate_quot(struct uart_port *port, unsigned int baud)
{ {
struct uart_port *port = info->port;
unsigned int quot; unsigned int quot;
/* Old HI/VHI/custom speed handling */ /*
if (baud == 38400 && * Old custom speed handling.
((port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)) */
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor; quot = port->custom_divisor;
else else
quot = port->uartclk / (16 * baud); quot = port->uartclk / (16 * baud);
...@@ -316,6 +316,58 @@ unsigned int uart_calculate_quot(struct uart_info *info, unsigned int baud) ...@@ -316,6 +316,58 @@ unsigned int uart_calculate_quot(struct uart_info *info, unsigned int baud)
return quot; return quot;
} }
/**
* uart_get_divisor - return uart clock divisor
* @port: uart_port structure describing the port.
* @tty: desired tty settings
* @old_termios: the original port settings, or NULL
*
* Calculate the uart clock divisor for the port. If the
* divisor is invalid, try the old termios setting. If
* the divisor is still invalid, we try 9600 baud.
*
* Update the @termios structure to reflect the baud rate
* we're actually going to be using.
*
* If 9600 baud fails, we return a zero divisor.
*/
static unsigned int
uart_get_divisor(struct uart_port *port, struct tty_struct *tty,
struct termios *old_termios)
{
unsigned int quot, try;
for (try = 0; try < 3; try ++) {
unsigned int baud;
/* Determine divisor based on baud rate */
baud = uart_get_baud_rate(port, tty);
quot = uart_calculate_quot(port, baud);
if (quot)
break;
/*
* Oops, the quotient was zero. Try again with
* the old baud rate if possible.
*/
tty->termios->c_cflag &= ~CBAUD;
if (old_termios) {
tty->termios->c_cflag |=
(old_termios->c_cflag & CBAUD);
old_termios = NULL;
continue;
}
/*
* As a last resort, if the quotient is zero,
* default to 9600 bps
*/
tty->termios->c_cflag |= B9600;
}
return quot;
}
static void static void
uart_change_speed(struct uart_info *info, struct termios *old_termios) uart_change_speed(struct uart_info *info, struct termios *old_termios)
{ {
...@@ -355,33 +407,7 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios) ...@@ -355,33 +407,7 @@ uart_change_speed(struct uart_info *info, struct termios *old_termios)
if (cflag & PARENB) if (cflag & PARENB)
bits++; bits++;
for (try = 0; try < 3; try ++) { quot = uart_get_divisor(port, tty, old_termios);
unsigned int baud;
/* Determine divisor based on baud rate */
baud = uart_get_baud_rate(port, info->tty);
quot = uart_calculate_quot(info, baud);
if (quot)
break;
/*
* Oops, the quotient was zero. Try again with
* the old baud rate if possible.
*/
info->tty->termios->c_cflag &= ~CBAUD;
if (old_termios) {
info->tty->termios->c_cflag |=
(old_termios->c_cflag & CBAUD);
old_termios = NULL;
continue;
}
/*
* As a last resort, if the quotient is zero,
* default to 9600 bps
*/
info->tty->termios->c_cflag |= B9600;
}
/* /*
* The total number of bits to be transmitted in the fifo. * The total number of bits to be transmitted in the fifo.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment