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

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

tty: serial: qcom_geni_serial: Remove interrupt storm



Disable M_TX_FIFO_WATERMARK_EN after we've sent all data for a given
transaction so we don't continue to receive a flurry of free space
interrupts while waiting for the M_CMD_DONE notification. Re-enable the
watermark when establishing the next transaction.

Also clear the watermark interrupt after filling the FIFO so we do not
receive notification again prior to actually having free space.

Change-Id: I31a2f495328fb7e67bc7e8eb112325f4017155a3
Signed-off-by: default avatarRyan Case <ryandcase@chromium.org>
Git-commit: 64a428077758383518c258641e81d57fcd454792
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 7044d43f
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -1306,6 +1306,7 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done,
	unsigned int fifo_width_bytes =
		(uart_console(uport) ? 1 : (msm_port->tx_fifo_width >> 3));
	int temp_tail = 0;
	int irq_en;

	tx_fifo_status = geni_read_reg_nolog(uport->membase,
					SE_GENI_TX_FIFO_STATUS);
@@ -1336,6 +1337,12 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done,
	if (!msm_port->cur_tx_remaining) {
		msm_geni_serial_setup_tx(uport, pending);
		msm_port->cur_tx_remaining = pending;

		/* Re-enable WM interrupt when starting new transfer */
		irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN);
		if (!(irq_en & M_TX_FIFO_WATERMARK_EN))
			geni_write_reg_nolog(irq_en | M_TX_FIFO_WATERMARK_EN,
					uport->membase, SE_GENI_M_IRQ_EN);
	}

	bytes_remaining = xmit_size;
@@ -1363,7 +1370,24 @@ static int msm_geni_serial_handle_tx(struct uart_port *uport, bool done,
		wmb();
	}
	xmit->tail = temp_tail;

	/*
	 * The tx fifo watermark is level triggered and latched. Though we had
	 * cleared it in qcom_geni_serial_isr it will have already reasserted
	 * so we must clear it again here after our writes.
	 */
	geni_write_reg_nolog(M_TX_FIFO_WATERMARK_EN, uport->membase,
						SE_GENI_M_IRQ_CLEAR);

exit_handle_tx:
	if (!msm_port->cur_tx_remaining) {
		irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN);
		/* Clear WM interrupt post each transfer completion */
		if (irq_en & M_TX_FIFO_WATERMARK_EN)
			geni_write_reg_nolog(irq_en & ~M_TX_FIFO_WATERMARK_EN,
					uport->membase, SE_GENI_M_IRQ_EN);
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(uport);
	return 0;