2014-07-24 12:04:03

by Maxime Coquelin

[permalink] [raw]
Subject: [PATCH 0/2] serial: st-asc: Couple of fixes

This series contains two fixes for ST's ASC driver.

The first issue addressed is a Kernel BUG when using the console on a different
ASC instance than the one being probed.

The second one is an overflow during buad rate calculation when requested rate
is higher than about 262Kbauds.

Maxime Coquelin (2):
serial: st-asc: Don't call BUG in asc_console_setup()
serial: st-asc: Fix overflow in baudrate calculation

drivers/tty/serial/st-asc.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

--
1.9.1


2014-07-24 12:03:59

by Maxime Coquelin

[permalink] [raw]
Subject: [PATCH 1/2] serial: st-asc: Don't call BUG in asc_console_setup()

In order to prevent an asc instance to be used as early console, BUG_ON is
used on either mapbase or membase being NULL.

Problem is that this condition is also true when we set console to be a ttyASx
different to the first asc instance being probed.

Instead of calling BUG_ON, it now returns -ENXIO when either mapbase or
membase is NULL.

Signed-off-by: Maxime Coquelin <[email protected]>
---
drivers/tty/serial/st-asc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index f48b1cc..2369bc0 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -849,7 +849,8 @@ static int asc_console_setup(struct console *co, char *options)
* this to be called during the uart port registration when the
* driver gets probed and the port should be mapped at that point.
*/
- BUG_ON(ascport->port.mapbase == 0 || ascport->port.membase == NULL);
+ if (ascport->port.mapbase == 0 || ascport->port.membase == NULL)
+ return -ENXIO;

if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
--
1.9.1

2014-07-24 12:03:58

by Maxime Coquelin

[permalink] [raw]
Subject: [PATCH 2/2] serial: st-asc: Fix overflow in baudrate calculation

In the current calculation, if the required baud rate is above 262143,
we get an overflow.

This patch uses a 64bits variable to do the maths.
Also, we remove the '+1' to avoid a divide by zero if the input clock
rate is something unexpected.
Indeed, if the input clock rate is zero, it is preferable to be notified,
since the UART won't work anyway.

Signed-off-by: Maxime Coquelin <[email protected]>
---
drivers/tty/serial/st-asc.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index 2369bc0..7ac9902 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -533,12 +533,12 @@ static void asc_set_termios(struct uart_port *port, struct ktermios *termios,
* ASCBaudRate = ------------------------
* inputclock
*
- * However to keep the maths inside 32bits we divide top and
- * bottom by 64. The +1 is to avoid a divide by zero if the
- * input clock rate is something unexpected.
+ * To keep maths inside 64bits, we divide inputclock by 16.
*/
- u32 counter = (baud * 16384) / ((port->uartclk / 64) + 1);
- asc_out(port, ASC_BAUDRATE, counter);
+ u64 dividend = (u64)baud * (1 << 16);
+
+ do_div(dividend, port->uartclk / 16);
+ asc_out(port, ASC_BAUDRATE, dividend);
ctrl_val |= ASC_CTL_BAUDMODE;
}

--
1.9.1