serial: 8250_pci: replace switch-case by formula

This patch replaces a switch-case by a formula using rational best
approximation that does necessary calculations for byt_set_termios().

Below is a list of the calculations done for all defined baud rates. Each line
in a format: 1) numerator, 2) denominator, 3) prescaler, 4) Fuart, 5) port UART
clock, 6) list of baud rates with DLAB values.

4        5        16 80000000   80000000   2500000(2)
14       25       16 56000000   56000000   3500000(1)
16       25       16 64000000   64000000   500000(8),1000000(4),2000000(2),
					4000000(1)
24       25       16 96000000   96000000   1500000(4),3000000(2)
2180     3103     16 70254592   70254592   134(32768)
2304     3125     16 73728000   73728000   576000(8),1152000(4)
8192     15625    16 52428800   52428800   50(65536),200(16384)
9216     15625    16 58982400   58982400   1800(2048),57600(64),115200(32),
					230400(16),460800(8),921600(4),1843200(2)
12288    15625    16 78643200   78643200   75(65536),150(32768),300(16384),
					600(8192),1200(4096),2400(2048),
					4800(1024),9600(512),19200(256),38400(128)
9893     17154    16 57671680   57671680   110(32768)

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Peter Hurley <peter@hurleysoftware.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Andy Shevchenko 2015-03-13 18:51:12 +02:00 committed by Greg Kroah-Hartman
parent 49708c9e6c
commit 21947ba654
2 changed files with 10 additions and 31 deletions

View File

@ -21,6 +21,7 @@
#include <linux/serial_core.h>
#include <linux/8250_pci.h>
#include <linux/bitops.h>
#include <linux/rational.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@ -1393,45 +1394,22 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
struct ktermios *old)
{
unsigned int baud = tty_termios_baud_rate(termios);
unsigned int m, n;
unsigned long fref = 100000000, fuart = baud * 16;
unsigned long w = BIT(15) - 1;
unsigned long m, n;
u32 reg;
/* Get Fuart closer to Fref */
fuart *= rounddown_pow_of_two(fref / fuart);
/*
* For baud rates 0.5M, 1M, 1.5M, 2M, 2.5M, 3M, 3.5M and 4M the
* dividers must be adjusted.
*
* uartclk = (m / n) * 100 MHz, where m <= n
*/
switch (baud) {
case 500000:
case 1000000:
case 2000000:
case 4000000:
m = 64;
n = 100;
p->uartclk = 64000000;
break;
case 3500000:
m = 56;
n = 100;
p->uartclk = 56000000;
break;
case 1500000:
case 3000000:
m = 48;
n = 100;
p->uartclk = 48000000;
break;
case 2500000:
m = 40;
n = 100;
p->uartclk = 40000000;
break;
default:
m = 2304;
n = 3125;
p->uartclk = 73728000;
}
rational_best_approximation(fuart, fref, w, w, &m, &n);
p->uartclk = fuart;
/* Reset the clock */
reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT);

View File

@ -108,6 +108,7 @@ config SERIAL_8250_PCI
tristate "8250/16550 PCI device support" if EXPERT
depends on SERIAL_8250 && PCI
default SERIAL_8250
select RATIONAL
help
This builds standard PCI serial support. You may be able to
disable this feature if you only need legacy serial support.