aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorBen Dooks <ben.dooks@codethink.co.uk>2015-11-18 09:41:12 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-12-13 22:59:48 -0500
commit00661dd855b5b174aa176a9ab9437d86ef4f8f1a (patch)
tree1249ecfd5759347eb13ccf2cc6804cbf871012e5 /drivers/tty
parent1bc1f17b7f1ca320b389622e3c7fbf4ee8991f61 (diff)
ARM: meson: serial: don't reset port on uart startup
When the uart startup entry is called, do not reset the port as this could cause issues with anything left in the FIFO from a previous operation such as a console write. Move the hardware reset to probe time and simply clear the errors before enabling the port. This fixes the issue where the console could become corrupted as there where characters left in the output or output fifo when a user process such as systemd would open/close the uart to transmit characters. For example, you get: [ 3.252263] systemd[1]: Dete instead of: [ 3.338801] systemd[1]: Detected architecture arm. Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk> Tested-by: Carlo Caione <carlo@endlessm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/meson_uart.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index b9f0829ceda1..b87eb97e5e7a 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -241,10 +241,9 @@ static const char *meson_uart_type(struct uart_port *port)
241 return (port->type == PORT_MESON) ? "meson_uart" : NULL; 241 return (port->type == PORT_MESON) ? "meson_uart" : NULL;
242} 242}
243 243
244static int meson_uart_startup(struct uart_port *port) 244static void meson_uart_reset(struct uart_port *port)
245{ 245{
246 u32 val; 246 u32 val;
247 int ret = 0;
248 247
249 val = readl(port->membase + AML_UART_CONTROL); 248 val = readl(port->membase + AML_UART_CONTROL);
250 val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); 249 val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
@@ -252,6 +251,18 @@ static int meson_uart_startup(struct uart_port *port)
252 251
253 val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); 252 val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
254 writel(val, port->membase + AML_UART_CONTROL); 253 writel(val, port->membase + AML_UART_CONTROL);
254}
255
256static int meson_uart_startup(struct uart_port *port)
257{
258 u32 val;
259 int ret = 0;
260
261 val = readl(port->membase + AML_UART_CONTROL);
262 val |= AML_UART_CLR_ERR;
263 writel(val, port->membase + AML_UART_CONTROL);
264 val &= ~AML_UART_CLR_ERR;
265 writel(val, port->membase + AML_UART_CONTROL);
255 266
256 val |= (AML_UART_RX_EN | AML_UART_TX_EN); 267 val |= (AML_UART_RX_EN | AML_UART_TX_EN);
257 writel(val, port->membase + AML_UART_CONTROL); 268 writel(val, port->membase + AML_UART_CONTROL);
@@ -581,6 +592,12 @@ static int meson_uart_probe(struct platform_device *pdev)
581 meson_ports[pdev->id] = port; 592 meson_ports[pdev->id] = port;
582 platform_set_drvdata(pdev, port); 593 platform_set_drvdata(pdev, port);
583 594
595 /* reset port before registering (and possibly registering console) */
596 if (meson_uart_request_port(port) >= 0) {
597 meson_uart_reset(port);
598 meson_uart_release_port(port);
599 }
600
584 ret = uart_add_one_port(&meson_uart_driver, port); 601 ret = uart_add_one_port(&meson_uart_driver, port);
585 if (ret) 602 if (ret)
586 meson_ports[pdev->id] = NULL; 603 meson_ports[pdev->id] = NULL;