aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorBarry Song <Baohua.Song@csr.com>2013-01-16 01:49:27 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-17 20:18:55 -0500
commitac4ce718893c546f7a2d34ab55a8f75842399f86 (patch)
treed858a4fa3c2b9dca0e383324b00cfad96aebc893 /drivers/tty/serial
parente27a7d7977b07d701ba247e2ddb95466d95c898f (diff)
serial: sirf: only use lookup table to set baudrate when ioclk=150MHz
The fast lookup table to set baudrate is only right when ioclk is 150MHz. for most platforms, ioclk is 150MHz, but some boards might set ioclk to other frequency. so re-calc the clk_div_reg when ioclk is not 150MHz. this patch also gets clk in probe and puts it in remove. Signed-off-by: Barry Song <Baohua.Song@csr.com> Cc: Russell King <linux@arm.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/sirfsoc_uart.c28
-rw-r--r--drivers/tty/serial/sirfsoc_uart.h1
2 files changed, 22 insertions, 7 deletions
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c
index 8f3d6c091acc..6bbfe9934a4d 100644
--- a/drivers/tty/serial/sirfsoc_uart.c
+++ b/drivers/tty/serial/sirfsoc_uart.c
@@ -357,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
357 struct ktermios *old) 357 struct ktermios *old)
358{ 358{
359 struct sirfsoc_uart_port *sirfport = to_sirfport(port); 359 struct sirfsoc_uart_port *sirfport = to_sirfport(port);
360 unsigned long ioclk_rate;
361 unsigned long config_reg = 0; 360 unsigned long config_reg = 0;
362 unsigned long baud_rate; 361 unsigned long baud_rate;
363 unsigned long setted_baud; 362 unsigned long setted_baud;
@@ -369,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
369 int threshold_div; 368 int threshold_div;
370 int temp; 369 int temp;
371 370
372 ioclk_rate = 150000000;
373 switch (termios->c_cflag & CSIZE) { 371 switch (termios->c_cflag & CSIZE) {
374 default: 372 default:
375 case CS8: 373 case CS8:
@@ -425,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
425 sirfsoc_uart_disable_ms(port); 423 sirfsoc_uart_disable_ms(port);
426 } 424 }
427 425
428 /* common rate: fast calculation */ 426 if (port->uartclk == 150000000) {
429 for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) 427 /* common rate: fast calculation */
430 if (baud_rate == baudrate_to_regv[ic].baud_rate) 428 for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++)
431 clk_div_reg = baudrate_to_regv[ic].reg_val; 429 if (baud_rate == baudrate_to_regv[ic].baud_rate)
430 clk_div_reg = baudrate_to_regv[ic].reg_val;
431 }
432
432 setted_baud = baud_rate; 433 setted_baud = baud_rate;
433 /* arbitary rate setting */ 434 /* arbitary rate setting */
434 if (unlikely(clk_div_reg == 0)) 435 if (unlikely(clk_div_reg == 0))
435 clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, 436 clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk,
436 &setted_baud); 437 &setted_baud);
437 wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); 438 wr_regl(port, SIRFUART_DIVISOR, clk_div_reg);
438 439
@@ -691,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
691 goto err; 692 goto err;
692 } 693 }
693 694
695 sirfport->clk = clk_get(&pdev->dev, NULL);
696 if (IS_ERR(sirfport->clk)) {
697 ret = PTR_ERR(sirfport->clk);
698 goto clk_err;
699 }
700 clk_prepare_enable(sirfport->clk);
701 port->uartclk = clk_get_rate(sirfport->clk);
702
694 port->ops = &sirfsoc_uart_ops; 703 port->ops = &sirfsoc_uart_ops;
695 spin_lock_init(&port->lock); 704 spin_lock_init(&port->lock);
696 705
@@ -704,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
704 return 0; 713 return 0;
705 714
706port_err: 715port_err:
716 clk_disable_unprepare(sirfport->clk);
717 clk_put(sirfport->clk);
718clk_err:
707 platform_set_drvdata(pdev, NULL); 719 platform_set_drvdata(pdev, NULL);
708 if (sirfport->hw_flow_ctrl) 720 if (sirfport->hw_flow_ctrl)
709 pinctrl_put(sirfport->p); 721 pinctrl_put(sirfport->p);
@@ -718,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
718 platform_set_drvdata(pdev, NULL); 730 platform_set_drvdata(pdev, NULL);
719 if (sirfport->hw_flow_ctrl) 731 if (sirfport->hw_flow_ctrl)
720 pinctrl_put(sirfport->p); 732 pinctrl_put(sirfport->p);
733 clk_disable_unprepare(sirfport->clk);
734 clk_put(sirfport->clk);
721 uart_remove_one_port(&sirfsoc_uart_drv, port); 735 uart_remove_one_port(&sirfsoc_uart_drv, port);
722 return 0; 736 return 0;
723} 737}
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h
index 6431640c3163..85328ba0c4e3 100644
--- a/drivers/tty/serial/sirfsoc_uart.h
+++ b/drivers/tty/serial/sirfsoc_uart.h
@@ -163,6 +163,7 @@ struct sirfsoc_uart_port {
163 163
164 struct uart_port port; 164 struct uart_port port;
165 struct pinctrl *p; 165 struct pinctrl *p;
166 struct clk *clk;
166}; 167};
167 168
168/* Hardware Flow Control */ 169/* Hardware Flow Control */