diff options
author | Mitul Golani <mgolani@codeaurora.org> | 2019-07-18 11:54:55 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-10-03 10:34:58 -0700 |
commit | e53b45b0ae285e4ab0aeaaa380ed02640d25c368 (patch) | |
tree | 96b904f6ea90f0a7e5e0e93a4f2dc046c83849af | |
parent | 60a116f544f68c8909f608906e17ae842b8ae532 (diff) |
serial: msm_geni_serial: Fix UART hangLE.UM.2.3.3.r1-06400-QCS605.0
If a serial console write occurred while a UART transmit command was
waiting for a done signal then no further data would be sent until
something new kicked the system into gear. If there is already data
waiting in the circular buffer we must re-enable the tx watermark so we
receive the expected interrupts.
Change-Id: Ibef3a7e2fca72f2356d5d43845056cefb6b0d2a4
Signed-off-by: Ryan Case <ryandcase@chromium.org>
Git-commit: 663abb1a7a7ff8fea9ab0145463de7fcff823755
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Signed-off-by: Mitul Golani <mgolani@codeaurora.org>
Signed-off-by: Rama Krishna Phani A <rphani@codeaurora.org>
-rw-r--r-- | drivers/tty/serial/msm_geni_serial.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index c86026d4a563..425a0b17012d 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -759,6 +759,7 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, bool locked = true; unsigned long flags; unsigned int geni_status; + int irq_en; WARN_ON(co->index < 0 || co->index >= GENI_UART_NR_PORTS); @@ -787,12 +788,22 @@ static void msm_geni_serial_console_write(struct console *co, const char *s, } writel_relaxed(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); - } else if ((geni_status & M_GENI_CMD_ACTIVE) && !port->cur_tx_remaining) + } else if ((geni_status & M_GENI_CMD_ACTIVE) && + !port->cur_tx_remaining) { /* It seems we can interrupt existing transfers unless all data * has been sent, in which case we need to look for done first. */ msm_geni_serial_poll_cancel_tx(uport); + /* Enable WATERMARK interrupt for every new console write op */ + if (uart_circ_chars_pending(&uport->state->xmit)) { + irq_en = geni_read_reg_nolog(uport->membase, + SE_GENI_M_IRQ_EN); + geni_write_reg_nolog(irq_en | M_TX_FIFO_WATERMARK_EN, + uport->membase, SE_GENI_M_IRQ_EN); + } + } + __msm_geni_serial_console_write(uport, s, count); if (port->cur_tx_remaining) |