aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-03-07 03:31:43 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2012-04-25 11:03:39 -0400
commit3a9465fa2dc42a8ebc2fe9144f4dfa23d5899f85 (patch)
tree1aab9e15d798e4ecc482948e85724179931e39ef /drivers/tty
parent52dac6150580f356a96b9a49715f6234fbf00d3a (diff)
serial i.MX: do not depend on grouped clocks
the current i.MX clock support groups together unrelated clocks to a single clock which is then used by the driver. This can't be accomplished with the generic clock framework so we instead request the individual clocks in the driver. For i.MX there are generally three different clocks: ipg: bus clock (needed to access registers) ahb: dma relevant clock, sometimes referred to as hclk in the datasheet per: bit clock, pixel clock This patch changes the driver to request the individual clocks. Currently all clk_get will get the same clock until the SoCs are converted to the generic clock framework Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/imx.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index e7feceeebc2..267ec6da5af 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -204,7 +204,8 @@ struct imx_port {
204 unsigned int irda_inv_rx:1; 204 unsigned int irda_inv_rx:1;
205 unsigned int irda_inv_tx:1; 205 unsigned int irda_inv_tx:1;
206 unsigned short trcv_delay; /* transceiver delay */ 206 unsigned short trcv_delay; /* transceiver delay */
207 struct clk *clk; 207 struct clk *clk_ipg;
208 struct clk *clk_per;
208 struct imx_uart_data *devdata; 209 struct imx_uart_data *devdata;
209}; 210};
210 211
@@ -672,7 +673,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
672 * RFDIV is set such way to satisfy requested uartclk value 673 * RFDIV is set such way to satisfy requested uartclk value
673 */ 674 */
674 val = TXTL << 10 | RXTL; 675 val = TXTL << 10 | RXTL;
675 ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2) 676 ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2)
676 / sport->port.uartclk; 677 / sport->port.uartclk;
677 678
678 if(!ufcr_rfdiv) 679 if(!ufcr_rfdiv)
@@ -1285,7 +1286,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
1285 else 1286 else
1286 ucfr_rfdiv = 6 - ucfr_rfdiv; 1287 ucfr_rfdiv = 6 - ucfr_rfdiv;
1287 1288
1288 uartclk = clk_get_rate(sport->clk); 1289 uartclk = clk_get_rate(sport->clk_per);
1289 uartclk /= ucfr_rfdiv; 1290 uartclk /= ucfr_rfdiv;
1290 1291
1291 { /* 1292 { /*
@@ -1503,14 +1504,22 @@ static int serial_imx_probe(struct platform_device *pdev)
1503 sport->timer.function = imx_timeout; 1504 sport->timer.function = imx_timeout;
1504 sport->timer.data = (unsigned long)sport; 1505 sport->timer.data = (unsigned long)sport;
1505 1506
1506 sport->clk = clk_get(&pdev->dev, "uart"); 1507 sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
1507 if (IS_ERR(sport->clk)) { 1508 if (IS_ERR(sport->clk_ipg)) {
1508 ret = PTR_ERR(sport->clk); 1509 ret = PTR_ERR(sport->clk_ipg);
1509 goto unmap; 1510 goto unmap;
1510 } 1511 }
1511 clk_prepare_enable(sport->clk);
1512 1512
1513 sport->port.uartclk = clk_get_rate(sport->clk); 1513 sport->clk_per = devm_clk_get(&pdev->dev, "per");
1514 if (IS_ERR(sport->clk_per)) {
1515 ret = PTR_ERR(sport->clk_per);
1516 goto unmap;
1517 }
1518
1519 clk_prepare_enable(sport->clk_per);
1520 clk_prepare_enable(sport->clk_ipg);
1521
1522 sport->port.uartclk = clk_get_rate(sport->clk_per);
1514 1523
1515 imx_ports[sport->port.line] = sport; 1524 imx_ports[sport->port.line] = sport;
1516 1525
@@ -1531,8 +1540,8 @@ deinit:
1531 if (pdata && pdata->exit) 1540 if (pdata && pdata->exit)
1532 pdata->exit(pdev); 1541 pdata->exit(pdev);
1533clkput: 1542clkput:
1534 clk_disable_unprepare(sport->clk); 1543 clk_disable_unprepare(sport->clk_per);
1535 clk_put(sport->clk); 1544 clk_disable_unprepare(sport->clk_ipg);
1536unmap: 1545unmap:
1537 iounmap(sport->port.membase); 1546 iounmap(sport->port.membase);
1538free: 1547free:
@@ -1550,11 +1559,10 @@ static int serial_imx_remove(struct platform_device *pdev)
1550 1559
1551 platform_set_drvdata(pdev, NULL); 1560 platform_set_drvdata(pdev, NULL);
1552 1561
1553 if (sport) { 1562 uart_remove_one_port(&imx_reg, &sport->port);
1554 uart_remove_one_port(&imx_reg, &sport->port); 1563
1555 clk_disable_unprepare(sport->clk); 1564 clk_disable_unprepare(sport->clk_per);
1556 clk_put(sport->clk); 1565 clk_disable_unprepare(sport->clk_ipg);
1557 }
1558 1566
1559 if (pdata && pdata->exit) 1567 if (pdata && pdata->exit)
1560 pdata->exit(pdev); 1568 pdata->exit(pdev);