aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/imx.c')
-rw-r--r--drivers/serial/imx.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 8d6cb745bd93..9e2162ebf1bb 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -40,6 +40,7 @@
40#include <linux/tty_flip.h> 40#include <linux/tty_flip.h>
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 44
44#include <asm/io.h> 45#include <asm/io.h>
45#include <asm/irq.h> 46#include <asm/irq.h>
@@ -184,6 +185,7 @@ struct imx_port {
184 unsigned int old_status; 185 unsigned int old_status;
185 int txirq,rxirq,rtsirq; 186 int txirq,rxirq,rtsirq;
186 int have_rtscts:1; 187 int have_rtscts:1;
188 struct clk *clk;
187}; 189};
188 190
189/* 191/*
@@ -479,7 +481,8 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
479 * RFDIV is set such way to satisfy requested uartclk value 481 * RFDIV is set such way to satisfy requested uartclk value
480 */ 482 */
481 val = TXTL << 10 | RXTL; 483 val = TXTL << 10 | RXTL;
482 ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; 484 ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2)
485 / sport->port.uartclk;
483 486
484 if(!ufcr_rfdiv) 487 if(!ufcr_rfdiv)
485 ufcr_rfdiv = 1; 488 ufcr_rfdiv = 1;
@@ -916,7 +919,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
916 else 919 else
917 ucfr_rfdiv = 6 - ucfr_rfdiv; 920 ucfr_rfdiv = 6 - ucfr_rfdiv;
918 921
919 uartclk = imx_get_perclk1(); 922 uartclk = clk_get_rate(sport->clk);
920 uartclk /= ucfr_rfdiv; 923 uartclk /= ucfr_rfdiv;
921 924
922 { /* 925 { /*
@@ -1054,7 +1057,15 @@ static int serial_imx_probe(struct platform_device *pdev)
1054 init_timer(&sport->timer); 1057 init_timer(&sport->timer);
1055 sport->timer.function = imx_timeout; 1058 sport->timer.function = imx_timeout;
1056 sport->timer.data = (unsigned long)sport; 1059 sport->timer.data = (unsigned long)sport;
1057 sport->port.uartclk = imx_get_perclk1(); 1060
1061 sport->clk = clk_get(&pdev->dev, "uart_clk");
1062 if (IS_ERR(sport->clk)) {
1063 ret = PTR_ERR(sport->clk);
1064 goto unmap;
1065 }
1066 clk_enable(sport->clk);
1067
1068 sport->port.uartclk = clk_get_rate(sport->clk);
1058 1069
1059 imx_ports[pdev->id] = sport; 1070 imx_ports[pdev->id] = sport;
1060 1071
@@ -1069,6 +1080,8 @@ static int serial_imx_probe(struct platform_device *pdev)
1069 platform_set_drvdata(pdev, &sport->port); 1080 platform_set_drvdata(pdev, &sport->port);
1070 1081
1071 return 0; 1082 return 0;
1083unmap:
1084 iounmap(sport->port.membase);
1072free: 1085free:
1073 kfree(sport); 1086 kfree(sport);
1074 1087
@@ -1084,8 +1097,12 @@ static int serial_imx_remove(struct platform_device *pdev)
1084 1097
1085 platform_set_drvdata(pdev, NULL); 1098 platform_set_drvdata(pdev, NULL);
1086 1099
1087 if (sport) 1100 if (sport) {
1088 uart_remove_one_port(&imx_reg, &sport->port); 1101 uart_remove_one_port(&imx_reg, &sport->port);
1102 clk_put(sport->clk);
1103 }
1104
1105 clk_disable(sport->clk);
1089 1106
1090 if (pdata->exit) 1107 if (pdata->exit)
1091 pdata->exit(pdev); 1108 pdata->exit(pdev);