Skip to content

Commit

Permalink
serial: 8250_dw: Honor clk_round_rate errors in dw8250_set_termios
Browse files Browse the repository at this point in the history
clk_round_rate returns a signed long and may possibly return errors
in it, for example if there is no possible rate.

Till now dw8250_set_termios ignored any error, the signednes and would
just use the value as input to clk_set_rate. This of course falls apart
if there is an actual error, so check for errors and only try to set
a rate if the value is actually valid.

This turned up on some Rockchip platforms after commit
6a171b2 ("serial: 8250_dw: Allow hardware flow control to be used")
enabled set_termios callback in all cases, not only ACPI.

Fixes: 6a171b2 ("serial: 8250_dw: Allow hardware flow control to be used")
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Heiko Stuebner authored and Greg Kroah-Hartman committed Mar 14, 2017
1 parent 4495c08 commit 0949808
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions drivers/tty/serial/8250/8250_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,18 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
{
unsigned int baud = tty_termios_baud_rate(termios);
struct dw8250_data *d = p->private_data;
unsigned int rate;
long rate;
int ret;

if (IS_ERR(d->clk) || !old)
goto out;

clk_disable_unprepare(d->clk);
rate = clk_round_rate(d->clk, baud * 16);
ret = clk_set_rate(d->clk, rate);
if (rate < 0)
ret = rate;
else
ret = clk_set_rate(d->clk, rate);
clk_prepare_enable(d->clk);

if (!ret)
Expand Down

0 comments on commit 0949808

Please sign in to comment.