Loading drivers/tty/serial/msm_geni_serial.c +38 −12 Original line number Diff line number Diff line Loading @@ -204,6 +204,7 @@ struct msm_geni_serial_port { bool s_cmd; struct completion m_cmd_timeout; struct completion s_cmd_timeout; spinlock_t rx_lock; }; static const struct uart_ops msm_geni_serial_pops; Loading @@ -228,6 +229,7 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport); static int msm_geni_serial_runtime_resume(struct device *dev); static int msm_geni_serial_runtime_suspend(struct device *dev); static int msm_geni_serial_get_ver_info(struct uart_port *uport); static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport); static int uart_line_id; #define GET_DEV_PORT(uport) \ Loading Loading @@ -1422,6 +1424,7 @@ static int stop_rx_sequencer(struct uart_port *uport) unsigned long flags = 0; bool is_rx_active; unsigned int stale_delay; u32 dma_rx_status, s_irq_status; IPC_LOG_MSG(port->ipc_log_misc, "%s\n", __func__); Loading @@ -1446,6 +1449,25 @@ static int stop_rx_sequencer(struct uart_port *uport) stale_delay = (STALE_COUNT * SEC_TO_USEC) / port->cur_baud; stale_delay = (2 * stale_delay) + SYSTEM_DELAY; udelay(stale_delay); dma_rx_status = geni_read_reg_nolog(uport->membase, SE_DMA_RX_IRQ_STAT); /* The transfer is completed at HW level and the completion * interrupt is delayed. So process the transfer completion * before issuing the cancel command to resolve the race * btw cancel RX and completion interrupt. */ if (dma_rx_status) { s_irq_status = geni_read_reg_nolog(uport->membase, SE_GENI_S_IRQ_STATUS); geni_write_reg_nolog(s_irq_status, uport->membase, SE_GENI_S_IRQ_CLEAR); geni_se_dump_dbg_regs(&port->serial_rsc, uport->membase, port->ipc_log_misc); IPC_LOG_MSG(port->ipc_log_misc, "%s: Interrupt delay\n", __func__); handle_rx_dma_xfer(s_irq_status, uport); } } IPC_LOG_MSG(port->ipc_log_misc, "%s: Start 0x%x\n", Loading Loading @@ -1915,18 +1937,15 @@ static bool handle_tx_dma_xfer(u32 m_irq_status, struct uart_port *uport) SE_DMA_TX_IRQ_CLR); 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; return true; if (dma_tx_status & TX_DMA_DONE) msm_geni_serial_handle_dma_tx(uport); } if (m_irq_status & (M_CMD_CANCEL_EN | M_CMD_ABORT_EN)) ret = true; return ret; } Loading @@ -1935,7 +1954,10 @@ static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport) bool ret = false; bool drop_rx = false; struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); u32 dma_rx_status = geni_read_reg_nolog(uport->membase, u32 dma_rx_status; spin_lock(&msm_port->rx_lock); dma_rx_status = geni_read_reg_nolog(uport->membase, SE_DMA_RX_IRQ_STAT); if (dma_rx_status) { Loading @@ -1946,7 +1968,7 @@ static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport) IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.Reset done. 0x%x.\n", __func__, dma_rx_status); ret = true; return ret; goto exit; } if (dma_rx_status & UART_DMA_RX_ERRS) { Loading Loading @@ -1987,11 +2009,13 @@ static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport) if (dma_rx_status & (RX_EOT | RX_GENI_CANCEL_IRQ | RX_DMA_DONE)) ret = true; } if (s_irq_status & (S_CMD_CANCEL_EN | S_CMD_ABORT_EN)) ret = true; } exit: spin_unlock(&msm_port->rx_lock); return ret; } Loading Loading @@ -3236,6 +3260,8 @@ static int msm_geni_serial_probe(struct platform_device *pdev) */ if (uart_console(uport)) geni_se_remove_earlycon_icc_vote(dev_port->wrapper_dev); else spin_lock_init(&dev_port->rx_lock); exit_geni_serial_probe: IPC_LOG_MSG(dev_port->ipc_log_misc, "%s: ret:%d\n", Loading Loading
drivers/tty/serial/msm_geni_serial.c +38 −12 Original line number Diff line number Diff line Loading @@ -204,6 +204,7 @@ struct msm_geni_serial_port { bool s_cmd; struct completion m_cmd_timeout; struct completion s_cmd_timeout; spinlock_t rx_lock; }; static const struct uart_ops msm_geni_serial_pops; Loading @@ -228,6 +229,7 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport); static int msm_geni_serial_runtime_resume(struct device *dev); static int msm_geni_serial_runtime_suspend(struct device *dev); static int msm_geni_serial_get_ver_info(struct uart_port *uport); static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport); static int uart_line_id; #define GET_DEV_PORT(uport) \ Loading Loading @@ -1422,6 +1424,7 @@ static int stop_rx_sequencer(struct uart_port *uport) unsigned long flags = 0; bool is_rx_active; unsigned int stale_delay; u32 dma_rx_status, s_irq_status; IPC_LOG_MSG(port->ipc_log_misc, "%s\n", __func__); Loading @@ -1446,6 +1449,25 @@ static int stop_rx_sequencer(struct uart_port *uport) stale_delay = (STALE_COUNT * SEC_TO_USEC) / port->cur_baud; stale_delay = (2 * stale_delay) + SYSTEM_DELAY; udelay(stale_delay); dma_rx_status = geni_read_reg_nolog(uport->membase, SE_DMA_RX_IRQ_STAT); /* The transfer is completed at HW level and the completion * interrupt is delayed. So process the transfer completion * before issuing the cancel command to resolve the race * btw cancel RX and completion interrupt. */ if (dma_rx_status) { s_irq_status = geni_read_reg_nolog(uport->membase, SE_GENI_S_IRQ_STATUS); geni_write_reg_nolog(s_irq_status, uport->membase, SE_GENI_S_IRQ_CLEAR); geni_se_dump_dbg_regs(&port->serial_rsc, uport->membase, port->ipc_log_misc); IPC_LOG_MSG(port->ipc_log_misc, "%s: Interrupt delay\n", __func__); handle_rx_dma_xfer(s_irq_status, uport); } } IPC_LOG_MSG(port->ipc_log_misc, "%s: Start 0x%x\n", Loading Loading @@ -1915,18 +1937,15 @@ static bool handle_tx_dma_xfer(u32 m_irq_status, struct uart_port *uport) SE_DMA_TX_IRQ_CLR); 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; return true; if (dma_tx_status & TX_DMA_DONE) msm_geni_serial_handle_dma_tx(uport); } if (m_irq_status & (M_CMD_CANCEL_EN | M_CMD_ABORT_EN)) ret = true; return ret; } Loading @@ -1935,7 +1954,10 @@ static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport) bool ret = false; bool drop_rx = false; struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport); u32 dma_rx_status = geni_read_reg_nolog(uport->membase, u32 dma_rx_status; spin_lock(&msm_port->rx_lock); dma_rx_status = geni_read_reg_nolog(uport->membase, SE_DMA_RX_IRQ_STAT); if (dma_rx_status) { Loading @@ -1946,7 +1968,7 @@ static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport) IPC_LOG_MSG(msm_port->ipc_log_misc, "%s.Reset done. 0x%x.\n", __func__, dma_rx_status); ret = true; return ret; goto exit; } if (dma_rx_status & UART_DMA_RX_ERRS) { Loading Loading @@ -1987,11 +2009,13 @@ static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport) if (dma_rx_status & (RX_EOT | RX_GENI_CANCEL_IRQ | RX_DMA_DONE)) ret = true; } if (s_irq_status & (S_CMD_CANCEL_EN | S_CMD_ABORT_EN)) ret = true; } exit: spin_unlock(&msm_port->rx_lock); return ret; } Loading Loading @@ -3236,6 +3260,8 @@ static int msm_geni_serial_probe(struct platform_device *pdev) */ if (uart_console(uport)) geni_se_remove_earlycon_icc_vote(dev_port->wrapper_dev); else spin_lock_init(&dev_port->rx_lock); exit_geni_serial_probe: IPC_LOG_MSG(dev_port->ipc_log_misc, "%s: ret:%d\n", Loading