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

Commit 20c46f6f authored by Ritesh Kumar's avatar Ritesh Kumar Committed by Gerrit - the friendly Code Review server
Browse files

disp: msm: dsi: remove early return from dma_cmd_wait_for_done



In ASYNC wait mode, next command kickoff can happen before previous
command ISR execution is completed in below sequence:

ASYNC command A -> triggered

dsi_ctrl_isr for command A -> fired and executed
	atomic_set(&dsi_ctrl->dma_irq_trig, 1);

wait_for_done for command A -> returns early as
	dsi_ctrl->dma_irq_trig is 1

ASYNC Command B -> triggered

wait_for_done for command B -> waiting for cmd_dma_done

dsi_ctrl_isr for command A -> executes
	complete_all(&dsi_ctrl->irq_info.cmd_dma_done);

wait_for_done for command B -> returns success incorrectly based on
	complete_all of previous command isr and disable_status_interrupt()
	is not called.

This leads to refcount of dma_done going wrong and dsi_ctrl_isr is not
enabled on suspend resume.

To fix this issue, mark command transfer successful only based on
complete_all(cmd_dma_done). This way disable_status_interrupt() will be
always called either from dsi_ctrl_isr or wait_for_done().

Change-Id: I0379ea7ff82a1e077b95f6996d11d1722de00936
Signed-off-by: default avatarRitesh Kumar <riteshk@codeaurora.org>
parent 7c9c407f
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
@@ -390,13 +390,6 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct work_struct *work)
	dsi_hw_ops = dsi_ctrl->hw.ops;
	SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY);

	/*
	 * This atomic state will be set if ISR has been triggered,
	 * so the wait is not needed.
	 */
	if (atomic_read(&dsi_ctrl->dma_irq_trig))
		goto done;

	ret = wait_for_completion_timeout(
			&dsi_ctrl->irq_info.cmd_dma_done,
			msecs_to_jiffies(DSI_CTRL_TX_TO_MS));
@@ -416,8 +409,8 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct work_struct *work)
					DSI_SINT_CMD_MODE_DMA_DONE);
	}

done:
	dsi_ctrl->dma_wait_queued = false;
	SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_EXIT);
}

static int dsi_ctrl_check_state(struct dsi_ctrl *dsi_ctrl,