Skip to content

Commit

Permalink
imx: serial: use rational library function
Browse files Browse the repository at this point in the history
for calculation of numerator and denominator
used in baud rate setting, use generic library function
for optimum settings.

Signed-off-by: Oskar Schirmer <os@emlix.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Oskar Schirmer authored and torvalds committed Jun 11, 2009
1 parent 8759ef3 commit 534fca0
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 20 deletions.
1 change: 1 addition & 0 deletions drivers/serial/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ config SERIAL_IMX
bool "IMX serial port support"
depends on ARM && (ARCH_IMX || ARCH_MXC)
select SERIAL_CORE
select RATIONAL
help
If you have a machine based on a Motorola IMX CPU you
can enable its onboard serial port by enabling this option.
Expand Down
30 changes: 10 additions & 20 deletions drivers/serial/imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/clk.h>
#include <linux/rational.h>

#include <asm/io.h>
#include <asm/irq.h>
Expand Down Expand Up @@ -670,7 +671,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned long flags;
unsigned int ucr2, old_ucr1, old_txrxen, baud, quot;
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
unsigned int div, num, denom, ufcr;
unsigned int div, ufcr;
unsigned long num, denom;

/*
* If we don't support modem control lines, don't allow
Expand Down Expand Up @@ -772,32 +774,20 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
if (!div)
div = 1;

num = baud;
denom = port->uartclk / div / 16;
rational_best_approximation(16 * div * baud, sport->port.uartclk,
1 << 16, 1 << 16, &num, &denom);

/* shift num and denom right until they fit into 16 bits */
while (num > 0x10000 || denom > 0x10000) {
num >>= 1;
denom >>= 1;
}
if (num > 0)
num -= 1;
if (denom > 0)
denom -= 1;

writel(num, sport->port.membase + UBIR);
writel(denom, sport->port.membase + UBMR);

if (div == 7)
div = 6; /* 6 in RFDIV means divide by 7 */
else
div = 6 - div;
num -= 1;
denom -= 1;

ufcr = readl(sport->port.membase + UFCR);
ufcr = (ufcr & (~UFCR_RFDIV)) |
(div << 7);
writel(ufcr, sport->port.membase + UFCR);

writel(num, sport->port.membase + UBIR);
writel(denom, sport->port.membase + UBMR);

#ifdef ONEMS
writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS);
#endif
Expand Down

0 comments on commit 534fca0

Please sign in to comment.