diff options
Diffstat (limited to 'drivers/serial/imx.c')
-rw-r--r-- | drivers/serial/imx.c | 25 |
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; |
1083 | unmap: | ||
1084 | iounmap(sport->port.membase); | ||
1072 | free: | 1085 | free: |
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); |