Skip to content

Commit

Permalink
serial: sirf: only use lookup table to set baudrate when ioclk=150MHz
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Barry Song authored and Greg Kroah-Hartman committed Jan 18, 2013
1 parent e27a7d7 commit ac4ce71
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
28 changes: 21 additions & 7 deletions drivers/tty/serial/sirfsoc_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
struct ktermios *old)
{
struct sirfsoc_uart_port *sirfport = to_sirfport(port);
unsigned long ioclk_rate;
unsigned long config_reg = 0;
unsigned long baud_rate;
unsigned long setted_baud;
Expand All @@ -369,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
int threshold_div;
int temp;

ioclk_rate = 150000000;
switch (termios->c_cflag & CSIZE) {
default:
case CS8:
Expand Down Expand Up @@ -425,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
sirfsoc_uart_disable_ms(port);
}

/* common rate: fast calculation */
for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++)
if (baud_rate == baudrate_to_regv[ic].baud_rate)
clk_div_reg = baudrate_to_regv[ic].reg_val;
if (port->uartclk == 150000000) {
/* common rate: fast calculation */
for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++)
if (baud_rate == baudrate_to_regv[ic].baud_rate)
clk_div_reg = baudrate_to_regv[ic].reg_val;
}

setted_baud = baud_rate;
/* arbitary rate setting */
if (unlikely(clk_div_reg == 0))
clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate,
clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk,
&setted_baud);
wr_regl(port, SIRFUART_DIVISOR, clk_div_reg);

Expand Down Expand Up @@ -691,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
goto err;
}

sirfport->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(sirfport->clk)) {
ret = PTR_ERR(sirfport->clk);
goto clk_err;
}
clk_prepare_enable(sirfport->clk);
port->uartclk = clk_get_rate(sirfport->clk);

port->ops = &sirfsoc_uart_ops;
spin_lock_init(&port->lock);

Expand All @@ -704,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
return 0;

port_err:
clk_disable_unprepare(sirfport->clk);
clk_put(sirfport->clk);
clk_err:
platform_set_drvdata(pdev, NULL);
if (sirfport->hw_flow_ctrl)
pinctrl_put(sirfport->p);
Expand All @@ -718,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
if (sirfport->hw_flow_ctrl)
pinctrl_put(sirfport->p);
clk_disable_unprepare(sirfport->clk);
clk_put(sirfport->clk);
uart_remove_one_port(&sirfsoc_uart_drv, port);
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/tty/serial/sirfsoc_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct sirfsoc_uart_port {

struct uart_port port;
struct pinctrl *p;
struct clk *clk;
};

/* Hardware Flow Control */
Expand Down

0 comments on commit ac4ce71

Please sign in to comment.