Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f9a8203 authored by Ryan Case's avatar Ryan Case Committed by Gerrit - the friendly Code Review server
Browse files

tty: serial: qcom_geni_serial: Fix UART hang



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: I89ae1c21942350dea25052ba9dea9080778f6d79
Signed-off-by: default avatarRyan Case <ryandcase@chromium.org>
Git-commit: 663abb1a7a7ff8fea9ab0145463de7fcff823755
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[msavaliy@codeaurora.org: Applied patch to downstream file - msm_geni_serial.c]
Signed-off-by: default avatarMukesh Kumar Savaliya <msavaliy@codeaurora.org>
parent 70b1056f
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -775,6 +775,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);

@@ -803,12 +804,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 WM 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)