Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac4ce718 authored by Barry Song's avatar Barry Song Committed by Greg Kroah-Hartman
Browse files

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: default avatarBarry Song <Baohua.Song@csr.com>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e27a7d79
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -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;
@@ -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:
@@ -425,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
			sirfsoc_uart_disable_ms(port);
	}

	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);

@@ -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);

@@ -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);
@@ -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;
}
+1 −0
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ struct sirfsoc_uart_port {

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

/* Hardware Flow Control */