aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitul Golani <mgolani@codeaurora.org>2019-07-18 11:54:55 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2019-10-03 10:34:58 -0700
commite53b45b0ae285e4ab0aeaaa380ed02640d25c368 (patch)
tree96b904f6ea90f0a7e5e0e93a4f2dc046c83849af
parent60a116f544f68c8909f608906e17ae842b8ae532 (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.c13
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)