aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/imx.c
diff options
context:
space:
mode:
authorOskar Schirmer <os@emlix.com>2009-06-11 09:52:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:51:08 -0400
commit534fca068ec8063ec8b67626b3eb34ba6ec86967 (patch)
tree576daa60818342ba8eedbe8d01300b9b59511288 /drivers/serial/imx.c
parent8759ef32d992fc6c0bcbe40fca7aa302190918a5 (diff)
imx: serial: use rational library function
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>
Diffstat (limited to 'drivers/serial/imx.c')
-rw-r--r--drivers/serial/imx.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index cbd4f3224643..0de81f71f884 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -41,6 +41,7 @@
41#include <linux/serial_core.h> 41#include <linux/serial_core.h>
42#include <linux/serial.h> 42#include <linux/serial.h>
43#include <linux/clk.h> 43#include <linux/clk.h>
44#include <linux/rational.h>
44 45
45#include <asm/io.h> 46#include <asm/io.h>
46#include <asm/irq.h> 47#include <asm/irq.h>
@@ -670,7 +671,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
670 unsigned long flags; 671 unsigned long flags;
671 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; 672 unsigned int ucr2, old_ucr1, old_txrxen, baud, quot;
672 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; 673 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
673 unsigned int div, num, denom, ufcr; 674 unsigned int div, ufcr;
675 unsigned long num, denom;
674 676
675 /* 677 /*
676 * If we don't support modem control lines, don't allow 678 * If we don't support modem control lines, don't allow
@@ -772,32 +774,20 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
772 if (!div) 774 if (!div)
773 div = 1; 775 div = 1;
774 776
775 num = baud; 777 rational_best_approximation(16 * div * baud, sport->port.uartclk,
776 denom = port->uartclk / div / 16; 778 1 << 16, 1 << 16, &num, &denom);
777 779
778 /* shift num and denom right until they fit into 16 bits */ 780 num -= 1;
779 while (num > 0x10000 || denom > 0x10000) { 781 denom -= 1;
780 num >>= 1;
781 denom >>= 1;
782 }
783 if (num > 0)
784 num -= 1;
785 if (denom > 0)
786 denom -= 1;
787
788 writel(num, sport->port.membase + UBIR);
789 writel(denom, sport->port.membase + UBMR);
790
791 if (div == 7)
792 div = 6; /* 6 in RFDIV means divide by 7 */
793 else
794 div = 6 - div;
795 782
796 ufcr = readl(sport->port.membase + UFCR); 783 ufcr = readl(sport->port.membase + UFCR);
797 ufcr = (ufcr & (~UFCR_RFDIV)) | 784 ufcr = (ufcr & (~UFCR_RFDIV)) |
798 (div << 7); 785 (div << 7);
799 writel(ufcr, sport->port.membase + UFCR); 786 writel(ufcr, sport->port.membase + UFCR);
800 787
788 writel(num, sport->port.membase + UBIR);
789 writel(denom, sport->port.membase + UBMR);
790
801#ifdef ONEMS 791#ifdef ONEMS
802 writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS); 792 writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS);
803#endif 793#endif