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

Commit 8bb75ef6 authored by Mitul Golani's avatar Mitul Golani Committed by Chandana Kishori Chiluveru
Browse files

serial: msm_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: I6375748dfa4ff0f159874e74abffaf5db180be39
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


Signed-off-by: default avatarMitul Golani <mgolani@codeaurora.org>
Signed-off-by: default avatarRama Krishna Phani A <rphani@codeaurora.org>
parent 6ae5e1ff
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -1302,6 +1302,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);
@@ -1332,6 +1333,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 WATERMARK interrupt while 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;
@@ -1359,7 +1366,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) {
		/* Clear WATERMARK interrupt for each transfer completion */
		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);
	}

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