aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2018-01-19 11:02:05 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-01-22 08:13:40 -0500
commitc14b65feac9ebed649d6fe79c6b6d64d21d0287d (patch)
treef3c8e24ec266f46b2b7d85c28e19c584514319d5
parenta0075d168a19dab5e015a03ffafbd6ab8e7d0c04 (diff)
serial: 8250_dw: Revert "Improve clock rate setting"
The commit de9e33bdfa22 ("serial: 8250_dw: Improve clock rate setting") obviously tries to cure symptoms, and not a root cause. The root cause is the non-flexible rate calculation inside the corresponding clock driver. What we need is to provide maximum UART divisor value to the clock driver to allow it do the job transparently to the caller. Since from the initial commit message I have got no clue which clock driver actually needs to be amended, I leave this exercise to the people who know better the case. Moreover, it seems [1] the fix introduced a regression. And possible even one more [2]. Taking above, revert the commit de9e33bdfa22 for now. [1]: https://www.spinics.net/lists/linux-serial/msg28872.html [2]: https://github.com/Dunedan/mbp-2016-linux/issues/29#issuecomment-357583782 Fixes: de9e33bdfa22 ("serial: 8250_dw: Improve clock rate setting") Cc: stable <stable@vger.kernel.org> # 4.15 Cc: Ed Blake <ed.blake@sondrel.com> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com> Cc: Lukas Wunner <lukas@wunner.de> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/8250/8250_dw.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index bda75d317d24..cd1b94a0f451 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -252,31 +252,25 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
252 struct ktermios *old) 252 struct ktermios *old)
253{ 253{
254 unsigned int baud = tty_termios_baud_rate(termios); 254 unsigned int baud = tty_termios_baud_rate(termios);
255 unsigned int target_rate, min_rate, max_rate;
256 struct dw8250_data *d = p->private_data; 255 struct dw8250_data *d = p->private_data;
257 long rate; 256 long rate;
258 int i, ret; 257 int ret;
259 258
260 if (IS_ERR(d->clk) || !old) 259 if (IS_ERR(d->clk) || !old)
261 goto out; 260 goto out;
262 261
263 /* Find a clk rate within +/-1.6% of an integer multiple of baudx16 */ 262 clk_disable_unprepare(d->clk);
264 target_rate = baud * 16; 263 rate = clk_round_rate(d->clk, baud * 16);
265 min_rate = target_rate - (target_rate >> 6); 264 if (rate < 0)
266 max_rate = target_rate + (target_rate >> 6); 265 ret = rate;
267 266 else if (rate == 0)
268 for (i = 1; i <= UART_DIV_MAX; i++) { 267 ret = -ENOENT;
269 rate = clk_round_rate(d->clk, i * target_rate); 268 else
270 if (rate >= i * min_rate && rate <= i * max_rate)
271 break;
272 }
273 if (i <= UART_DIV_MAX) {
274 clk_disable_unprepare(d->clk);
275 ret = clk_set_rate(d->clk, rate); 269 ret = clk_set_rate(d->clk, rate);
276 clk_prepare_enable(d->clk); 270 clk_prepare_enable(d->clk);
277 if (!ret) 271
278 p->uartclk = rate; 272 if (!ret)
279 } 273 p->uartclk = rate;
280 274
281out: 275out:
282 p->status &= ~UPSTAT_AUTOCTS; 276 p->status &= ~UPSTAT_AUTOCTS;