aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2011-10-24 05:47:40 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-12-22 20:06:55 -0500
commit046c217c65a7670b4ee1aecdb9854284e32b2d6c (patch)
tree4219455716aaebe392d8d3094b85ee733dc8f77d /drivers/tty
parent4d84e970d0faec772a9eaa818feee38aeca121b2 (diff)
ARM: S3C2440: move handling of fclk/n clock to platform code
s3c2440 uses fclk/n (fclk divided by n) clock as one of the possible clocks used to generate the baud rate clock. The divider 'n' in this case can be logically represented outside of the uart controller. This patch creates a new clock by name "fclk_n" for s3c2440 based platforms to represent the fclk/n clock in the platform code. This clock provides a get_rate callback that checks the UCON0/1/2 registers to determine the clock rate. The samsung uart driver would receive the "fclk_n" clock name as one of the possible baud rate clock options and the driver need not determine clock rate of fclk/n. Cc: Ben Dooks <ben-linux@fluff.org> Cc: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/s3c2440.c33
-rw-r--r--drivers/tty/serial/samsung.c21
2 files changed, 3 insertions, 51 deletions
diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c
index 1d0c324b813f..4498828630f1 100644
--- a/drivers/tty/serial/s3c2440.c
+++ b/drivers/tty/serial/s3c2440.c
@@ -39,7 +39,7 @@ static int s3c2440_serial_setsource(struct uart_port *port,
39 ucon |= S3C2440_UCON_UCLK; 39 ucon |= S3C2440_UCON_UCLK;
40 else if (strcmp(clk->name, "pclk") == 0) 40 else if (strcmp(clk->name, "pclk") == 0)
41 ucon |= S3C2440_UCON_PCLK; 41 ucon |= S3C2440_UCON_PCLK;
42 else if (strcmp(clk->name, "fclk") == 0) 42 else if (strcmp(clk->name, "fclk_n") == 0)
43 ucon |= S3C2440_UCON_FCLK; 43 ucon |= S3C2440_UCON_FCLK;
44 else { 44 else {
45 printk(KERN_ERR "unknown clock source %s\n", clk->name); 45 printk(KERN_ERR "unknown clock source %s\n", clk->name);
@@ -55,7 +55,6 @@ static int s3c2440_serial_getsource(struct uart_port *port,
55 struct s3c24xx_uart_clksrc *clk) 55 struct s3c24xx_uart_clksrc *clk)
56{ 56{
57 unsigned long ucon = rd_regl(port, S3C2410_UCON); 57 unsigned long ucon = rd_regl(port, S3C2410_UCON);
58 unsigned long ucon0, ucon1, ucon2;
59 58
60 switch (ucon & S3C2440_UCON_CLKMASK) { 59 switch (ucon & S3C2440_UCON_CLKMASK) {
61 case S3C2440_UCON_UCLK: 60 case S3C2440_UCON_UCLK:
@@ -70,34 +69,8 @@ static int s3c2440_serial_getsource(struct uart_port *port,
70 break; 69 break;
71 70
72 case S3C2440_UCON_FCLK: 71 case S3C2440_UCON_FCLK:
73 /* the fun of calculating the uart divisors on 72 clk->divisor = 1;
74 * the s3c2440 */ 73 clk->name = "fclk_n";
75
76 ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
77 ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
78 ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
79
80 printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
81
82 ucon0 &= S3C2440_UCON0_DIVMASK;
83 ucon1 &= S3C2440_UCON1_DIVMASK;
84 ucon2 &= S3C2440_UCON2_DIVMASK;
85
86 if (ucon0 != 0) {
87 clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
88 clk->divisor += 6;
89 } else if (ucon1 != 0) {
90 clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
91 clk->divisor += 21;
92 } else if (ucon2 != 0) {
93 clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
94 clk->divisor += 36;
95 } else {
96 /* manual calims 44, seems to be 9 */
97 clk->divisor = 9;
98 }
99
100 clk->name = "fclk";
101 break; 74 break;
102 } 75 }
103 76
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 51cfb9f11665..fc242b2fd368 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -649,27 +649,6 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
649 if (cfg->clocks_size == 0) 649 if (cfg->clocks_size == 0)
650 clkp = &tmp_clksrc; 650 clkp = &tmp_clksrc;
651 651
652 /* check to see if we're sourcing fclk, and if so we're
653 * going to have to update the clock source
654 */
655
656 if (strcmp(clkp->name, "fclk") == 0) {
657 struct s3c24xx_uart_clksrc src;
658
659 s3c24xx_serial_getsource(port, &src);
660
661 /* check that the port already using fclk, and if
662 * not, then re-select fclk
663 */
664
665 if (strcmp(src.name, clkp->name) == 0) {
666 s3c24xx_serial_setsource(port, clkp);
667 s3c24xx_serial_getsource(port, &src);
668 }
669
670 clkp->divisor = src.divisor;
671 }
672
673 s3c24xx_serial_calcbaud(res, port, clkp, baud); 652 s3c24xx_serial_calcbaud(res, port, clkp, baud);
674 best = res; 653 best = res;
675 resptr = best + 1; 654 resptr = best + 1;