From 81ad4ef40777275a1de65e1d569b0aa2960c7cf0 Mon Sep 17 00:00:00 2001 From: Vara Reddy Date: Mon, 25 Nov 2019 16:47:26 -0800 Subject: [PATCH] drm/msm/dsi: fix dsi command dma async race condition Change will be removing checking and clearing dsi cmd done interrupt in commit thread and in workqueue context, which can race with dsi isr, when it tries to clear the interrupt. Change-Id: I96e7f8dffed1af3cec0c7668ab1729337d4b260e Signed-off-by: Vara Reddy Signed-off-by: Satya Rama Aditya Pinapala --- msm/dsi/dsi_ctrl.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 6aa7aea0b2..37d040d989 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -269,10 +269,6 @@ dsi_ctrl_get_aspace(struct dsi_ctrl *dsi_ctrl, static void dsi_ctrl_flush_cmd_dma_queue(struct dsi_ctrl *dsi_ctrl) { - u32 status; - u32 mask = DSI_CMD_MODE_DMA_DONE; - struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops; - /* * If a command is triggered right after another command, * check if the previous command transfer is completed. If @@ -281,21 +277,8 @@ static void dsi_ctrl_flush_cmd_dma_queue(struct dsi_ctrl *dsi_ctrl) * completed before triggering the next command by * flushing the workqueue. */ - status = dsi_hw_ops.get_interrupt_status(&dsi_ctrl->hw); if (atomic_read(&dsi_ctrl->dma_irq_trig)) { cancel_work_sync(&dsi_ctrl->dma_cmd_wait); - } else if (status & mask) { - atomic_set(&dsi_ctrl->dma_irq_trig, 1); - status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE); - dsi_hw_ops.clear_interrupt_status( - &dsi_ctrl->hw, - status); - dsi_ctrl_disable_status_interrupt(dsi_ctrl, - DSI_SINT_CMD_MODE_DMA_DONE); - complete_all(&dsi_ctrl->irq_info.cmd_dma_done); - cancel_work_sync(&dsi_ctrl->dma_cmd_wait); - DSI_CTRL_DEBUG(dsi_ctrl, - "dma_tx done but irq not yet triggered\n"); } else { flush_workqueue(dsi_ctrl->dma_cmd_workq); } @@ -319,24 +302,11 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct work_struct *work) */ if (atomic_read(&dsi_ctrl->dma_irq_trig)) goto done; - /* - * If IRQ wasn't triggered check interrupt status register for - * transfer done before waiting. - */ - status = dsi_hw_ops.get_interrupt_status(&dsi_ctrl->hw); - if (status & mask) { - status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE); - dsi_hw_ops.clear_interrupt_status(&dsi_ctrl->hw, - status); - dsi_ctrl_disable_status_interrupt(dsi_ctrl, - DSI_SINT_CMD_MODE_DMA_DONE); - goto done; - } ret = wait_for_completion_timeout( &dsi_ctrl->irq_info.cmd_dma_done, msecs_to_jiffies(DSI_CTRL_TX_TO_MS)); - if (ret == 0) { + if (ret == 0 && !atomic_read(&dsi_ctrl->dma_irq_trig)) { status = dsi_hw_ops.get_interrupt_status(&dsi_ctrl->hw); if (status & mask) { status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE);