kernel: bump 4.9 to 4.9.108 for 18.06
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.9 / 950-0195-amba_pl011-Round-input-clock-up.patch
1 From 0360d687752df3c5546dd1534904a6e0168b6360 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Wed, 1 Mar 2017 16:07:39 +0000
4 Subject: [PATCH] amba_pl011: Round input clock up
5
6 The UART clock is initialised to be as close to the requested
7 frequency as possible without exceeding it. Now that there is a
8 clock manager that returns the actual frequencies, an expected
9 48MHz clock is reported as 47999625. If the requested baudrate
10 == requested clock/16, there is no headroom and the slight
11 reduction in actual clock rate results in failure.
12
13 Detect cases where it looks like a "round" clock was chosen and
14 adjust the reported clock to match that "round" value. As the
15 code comment says:
16
17 /*
18 * If increasing a clock by less than 0.1% changes it
19 * from ..999.. to ..000.., round up.
20 */
21
22 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
23 ---
24 drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++--
25 1 file changed, 21 insertions(+), 2 deletions(-)
26
27 --- a/drivers/tty/serial/amba-pl011.c
28 +++ b/drivers/tty/serial/amba-pl011.c
29 @@ -1651,6 +1651,23 @@ static void pl011_put_poll_char(struct u
30
31 #endif /* CONFIG_CONSOLE_POLL */
32
33 +unsigned long pl011_clk_round(unsigned long clk)
34 +{
35 + unsigned long scaler;
36 +
37 + /*
38 + * If increasing a clock by less than 0.1% changes it
39 + * from ..999.. to ..000.., round up.
40 + */
41 + scaler = 1;
42 + while (scaler * 100000 < clk)
43 + scaler *= 10;
44 + if ((clk + scaler - 1)/scaler % 1000 == 0)
45 + clk = (clk/scaler + 1) * scaler;
46 +
47 + return clk;
48 +}
49 +
50 static int pl011_hwinit(struct uart_port *port)
51 {
52 struct uart_amba_port *uap =
53 @@ -1667,7 +1684,7 @@ static int pl011_hwinit(struct uart_port
54 if (retval)
55 return retval;
56
57 - uap->port.uartclk = clk_get_rate(uap->clk);
58 + uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
59
60 /* Clear pending error and receive interrupts */
61 pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS |
62 @@ -2305,7 +2322,7 @@ static int __init pl011_console_setup(st
63 plat->init();
64 }
65
66 - uap->port.uartclk = clk_get_rate(uap->clk);
67 + uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
68
69 if (uap->vendor->fixed_options) {
70 baud = uap->fixed_baud;
71 @@ -2432,6 +2449,7 @@ static struct uart_driver amba_reg = {
72 .cons = AMBA_CONSOLE,
73 };
74
75 +#if 0
76 static int pl011_probe_dt_alias(int index, struct device *dev)
77 {
78 struct device_node *np;
79 @@ -2463,6 +2481,7 @@ static int pl011_probe_dt_alias(int inde
80
81 return ret;
82 }
83 +#endif
84
85 /* unregisters the driver also if no more ports are left */
86 static void pl011_unregister_port(struct uart_amba_port *uap)