From c2ca8e5398d207fc08dfb059d18afd9cfecf825a Mon Sep 17 00:00:00 2001 From: Akash Asthana Date: Wed, 17 Jun 2020 12:21:31 +0530 Subject: [PATCH] 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 --- drivers/tty/serial/msm_geni_serial.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c index ed8e9f5bc806..3d4c8571ccf3 100644 --- a/drivers/tty/serial/msm_geni_serial.c +++ b/drivers/tty/serial/msm_geni_serial.c @@ -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;