serial: msm_geni_serial: Fix DMA TX FSM reset sequence

TX FSM reset command generates TX_RESET_DONE & TX_DMA_DONE interrupt bits.
Upon receiving TX_DMA_DONE we initiate new TX transfer for the pending
bytes present in tty uart circular buffer. That leaves TX sequencer active
after reset sequence. That can result into all kinds of SMMU crash where
client initiates new TX DMA transfer without knowing that we have already
a transfer queued. This is unexpected behaviour because we expect TX
sequencer and DMA engine to go IDLE after reset.

To fix above scenario, don't handle TX_DMA_DONE upon reciving
TX_RESET_DONE.

Also, add IPC logs to get_mctrl function to get the IOS status.

Change-Id: Ib76750b5e2c6ec5bf993c341c258791e471672d2
Signed-off-by: Akash Asthana <akashast@codeaurora.org>
This commit is contained in:
Akash Asthana 2020-06-17 12:21:31 +05:30 • committed by Gerrit - the friendly Code Review server
commit c2ca8e5398

View file

@ -615,7 +615,8 @@ static unsigned int msm_geni_serial_get_mctrl(struct uart_port *uport)
geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS);
if (!(geni_ios & IO2_DATA_IN))
mctrl |= TIOCM_CTS;
IPC_LOG_MSG(port->ipc_log_misc, "%s: geni_ios:0x%x, mctrl:0x%x\n",
__func__, geni_ios, mctrl);
return mctrl;
}
@ -1839,14 +1840,17 @@ static bool handle_tx_dma_xfer(u32 m_irq_status, struct uart_port *uport)
geni_write_reg_nolog(dma_tx_status, uport->membase,
SE_DMA_TX_IRQ_CLR);
if (dma_tx_status & TX_DMA_DONE)
msm_geni_serial_handle_dma_tx(uport);
if (dma_tx_status & (TX_RESET_DONE | TX_GENI_CANCEL_IRQ))
ret = true;
if (m_irq_status & (M_CMD_CANCEL_EN | M_CMD_ABORT_EN))
ret = true;
if (ret)
return ret;
if (dma_tx_status & TX_DMA_DONE)
msm_geni_serial_handle_dma_tx(uport);
}
return ret;