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

Commit 43de0f4f authored by Petar Sivenov's avatar Petar Sivenov
Browse files

msm: camera: isp: fix pingpong status race condition



Frame request from userspace can happen at any moment relative to
frame. However usage of ping pong flag in this routine is considered
as if it is called between SOF and AXI IRQs. If frame request arrives
later, address is configured incorrectly. This change uses ping pong
taken during AXI irq - which is synchronous with change of ping pong
flag and uses it for next SOF to SOF interval, avoiding race
condition.

Change-Id: I6c99632e38214ee568d15aaa78e67a51ebac97df
Signed-off-by: default avatarPetar Sivenov <psiven@codeaurora.org>
parent 21a2ddca
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -451,6 +451,7 @@ struct msm_vfe_axi_stream {
	enum msm_stream_rdi_input_type  rdi_input_type;
	struct msm_isp_sw_framskip sw_skip;
	uint8_t sw_ping_pong_bit;
	uint8_t sw_sof_ping_pong_bit;
};

struct msm_vfe_axi_composite_info {
+15 −5
Original line number Diff line number Diff line
@@ -967,6 +967,7 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,
	struct msm_isp_event_data event_data;
	struct msm_vfe_sof_info *sof_info = NULL, *self_sof = NULL;
	enum msm_vfe_dual_hw_ms_type ms_type;
	struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
	int i, j;
	unsigned long flags;

@@ -974,6 +975,15 @@ void msm_isp_notify(struct vfe_device *vfe_dev, uint32_t event_type,

	switch (event_type) {
	case ISP_EVENT_SOF:
		for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
			if (SRC_TO_INTF(axi_data->stream_info[i].stream_src) ==
				frame_src) {
				/* update ping pong bit for controllable */
				/* output */
				axi_data->stream_info[i].sw_sof_ping_pong_bit =
				      axi_data->stream_info[i].sw_ping_pong_bit;
			}
		}
		if (frame_src == VFE_PIX_0) {
			if (vfe_dev->isp_sof_debug < ISP_SOF_DEBUG_COUNT)
				pr_err("%s: PIX0 frame id: %u\n", __func__,
@@ -3272,11 +3282,6 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
	}

	frame_src = SRC_TO_INTF(stream_info->stream_src);

	pingpong_status =
		vfe_dev->hw_info->vfe_ops.axi_ops.get_pingpong_status(
			vfe_dev);

	trace_msm_cam_isp_bufcount("msm_isp_request_frame:",
		vfe_dev->pdev->id, frame_id, frame_src);

@@ -3396,7 +3401,12 @@ static int msm_isp_request_frame(struct vfe_device *vfe_dev,
			dual_vfe_res->wm_reload_mask[vfe_id] = 0;
		}
		stream_info->sw_ping_pong_bit = 0;
		stream_info->sw_sof_ping_pong_bit = 0;
	} else if (stream_info->undelivered_request_cnt == 2) {
		if (stream_info->sw_sof_ping_pong_bit)
			pingpong_status = VFE_PING_FLAG;
		else
			pingpong_status = VFE_PONG_FLAG;
		rc = msm_isp_cfg_ping_pong_address(vfe_dev,
				stream_info, pingpong_status, 0);
		if (rc) {