Merge "msm: camera: Use wall clock for event timestamp"
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index d412435..8136c57 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -54,27 +54,34 @@
 	DISABLE_CAMIF_IMMEDIATELY
 };
 
+struct msm_isp_timestamp {
+	/*Monotonic clock for v4l2 buffer*/
+	struct timeval buf_time;
+	/*Wall clock for userspace event*/
+	struct timeval event_time;
+};
+
 struct msm_vfe_irq_ops {
 	void (*read_irq_status) (struct vfe_device *vfe_dev,
 		uint32_t *irq_status0, uint32_t *irq_status1);
 	void (*process_reg_update) (struct vfe_device *vfe_dev,
 		uint32_t irq_status0, uint32_t irq_status1,
-		struct timeval *tv);
+		struct msm_isp_timestamp *ts);
 	void (*process_reset_irq) (struct vfe_device *vfe_dev,
 		uint32_t irq_status0, uint32_t irq_status1);
 	void (*process_halt_irq) (struct vfe_device *vfe_dev,
 		uint32_t irq_status0, uint32_t irq_status1);
 	void (*process_camif_irq) (struct vfe_device *vfe_dev,
 		uint32_t irq_status0, uint32_t irq_status1,
-		struct timeval *tv);
+		struct msm_isp_timestamp *ts);
 	void (*process_axi_irq) (struct vfe_device *vfe_dev,
 		uint32_t irq_status0, uint32_t irq_status1,
-		struct timeval *tv);
+		struct msm_isp_timestamp *ts);
 	void (*process_error_irq) (struct vfe_device *vfe_dev,
 		uint32_t irq_status0, uint32_t irq_status1);
 	void (*process_stats_irq) (struct vfe_device *vfe_dev,
 		uint32_t irq_status0, uint32_t irq_status1,
-		struct timeval *tv);
+		struct msm_isp_timestamp *ts);
 };
 
 struct msm_vfe_axi_ops {
@@ -325,7 +332,7 @@
 	struct list_head list;
 	uint32_t vfeInterruptStatus0;
 	uint32_t vfeInterruptStatus1;
-	struct timeval tv;
+	struct msm_isp_timestamp ts;
 	uint8_t cmd_used;
 };
 
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index 750963c..b159e3c 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -170,7 +170,8 @@
 }
 
 static void msm_vfe32_process_camif_irq(struct vfe_device *vfe_dev,
-	uint32_t irq_status0, uint32_t irq_status1, struct timeval *tv)
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
 {
 	if (!(irq_status0 & 0x1F))
 		return;
@@ -178,12 +179,13 @@
 	if (irq_status0 & BIT(0)) {
 		ISP_DBG("%s: PIX0 frame id: %lu\n", __func__,
 			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
-		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, tv);
+		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
 	}
 }
 
 static void msm_vfe32_process_stats_irq(struct vfe_device *vfe_dev,
-	uint32_t irq_status0, uint32_t irq_status1, struct timeval *tv)
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
 {
 	/* todo: add stats specific code */
 	return;
@@ -321,7 +323,8 @@
 }
 
 static void msm_vfe32_process_reg_update(struct vfe_device *vfe_dev,
-	uint32_t irq_status0, uint32_t irq_status1, struct timeval *tv)
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
 {
 	if (!(irq_status0 & 0x20) && !(irq_status1 & 0x1C000000))
 		return;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index ed4aa7f..633ba85 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -284,7 +284,8 @@
 }
 
 static void msm_vfe40_process_camif_irq(struct vfe_device *vfe_dev,
-	uint32_t irq_status0, uint32_t irq_status1, struct timeval *tv)
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
 {
 	if (!(irq_status0 & 0xF))
 		return;
@@ -294,7 +295,7 @@
 		if (vfe_dev->axi_data.src_info[VFE_PIX_0].raw_stream_count > 0
 			&& vfe_dev->axi_data.src_info[VFE_PIX_0].
 			pix_stream_count == 0) {
-			msm_isp_sof_notify(vfe_dev, VFE_PIX_0, tv);
+			msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
 			msm_isp_update_framedrop_reg(vfe_dev);
 		}
 	}
@@ -445,20 +446,21 @@
 }
 
 static void msm_vfe40_process_reg_update(struct vfe_device *vfe_dev,
-	uint32_t irq_status0, uint32_t irq_status1, struct timeval *tv)
+	uint32_t irq_status0, uint32_t irq_status1,
+	struct msm_isp_timestamp *ts)
 {
 	uint32_t update_mask = 0xF;
 	if (!(irq_status0 & 0xF0))
 		return;
 
 	if (irq_status0 & BIT(4))
-		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, tv);
+		msm_isp_sof_notify(vfe_dev, VFE_PIX_0, ts);
 	if (irq_status0 & BIT(5))
-		msm_isp_sof_notify(vfe_dev, VFE_RAW_0, tv);
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_0, ts);
 	if (irq_status0 & BIT(6))
-		msm_isp_sof_notify(vfe_dev, VFE_RAW_1, tv);
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_1, ts);
 	if (irq_status0 & BIT(7))
-		msm_isp_sof_notify(vfe_dev, VFE_RAW_2, tv);
+		msm_isp_sof_notify(vfe_dev, VFE_RAW_2, ts);
 
 	if (vfe_dev->axi_data.stream_update)
 		msm_isp_axi_stream_update(vfe_dev);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index ac3ce0a..b3626e4 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -395,7 +395,7 @@
 }
 
 void msm_isp_sof_notify(struct vfe_device *vfe_dev,
-	enum msm_vfe_input_src frame_src, struct timeval *tv) {
+	enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts) {
 	struct msm_isp_event_data sof_event;
 	switch (frame_src) {
 	case VFE_PIX_0:
@@ -417,7 +417,7 @@
 	}
 
 	sof_event.frame_id = vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
-	sof_event.timestamp = *tv;
+	sof_event.timestamp = ts->event_time;
 	msm_isp_send_event(vfe_dev, ISP_EVENT_SOF, &sof_event);
 }
 
@@ -714,17 +714,18 @@
 
 static void msm_isp_process_done_buf(struct vfe_device *vfe_dev,
 	struct msm_vfe_axi_stream *stream_info, struct msm_isp_buffer *buf,
-	struct timeval *tv)
+	struct msm_isp_timestamp *ts)
 {
 	struct msm_isp_event_data buf_event;
 	uint32_t frame_id = vfe_dev->axi_data.
 		src_info[stream_info->stream_src].frame_id;
-	if (buf && tv) {
+	if (buf && ts) {
 		if (stream_info->buf_divert) {
 			vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
-				buf->bufq_handle, buf->buf_idx, tv, frame_id);
+				buf->bufq_handle, buf->buf_idx,
+				&ts->buf_time, frame_id);
 			buf_event.frame_id = frame_id;
-			buf_event.timestamp = *tv;
+			buf_event.timestamp = ts->event_time;
 			buf_event.u.buf_done.session_id =
 				stream_info->session_id;
 			buf_event.u.buf_done.stream_id =
@@ -736,7 +737,8 @@
 				vfe_dev, ISP_EVENT_BUF_DIVERT, &buf_event);
 		} else {
 			vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
-				buf->bufq_handle, buf->buf_idx, tv, frame_id);
+				buf->bufq_handle, buf->buf_idx,
+				&ts->buf_time, frame_id);
 		}
 	}
 }
@@ -980,7 +982,7 @@
 
 void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
 	uint32_t irq_status0, uint32_t irq_status1,
-	struct timeval *tv)
+	struct msm_isp_timestamp *ts)
 {
 	int i, rc = 0;
 	struct msm_isp_buffer *done_buf = NULL;
@@ -1026,7 +1028,7 @@
 				}
 				if (done_buf && !rc)
 					msm_isp_process_done_buf(vfe_dev,
-					stream_info, done_buf, tv);
+					stream_info, done_buf, ts);
 			}
 		}
 		wm_mask &= ~(comp_info->stream_composite_mask);
@@ -1051,7 +1053,7 @@
 			}
 			if (done_buf && !rc)
 				msm_isp_process_done_buf(vfe_dev,
-				stream_info, done_buf, tv);
+				stream_info, done_buf, ts);
 		}
 	}
 	return;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
index 9765ae2..de9d048 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
@@ -55,8 +55,8 @@
 void msm_isp_update_framedrop_reg(struct vfe_device *vfe_dev);
 void msm_isp_update_framedrop_count(struct vfe_device *vfe_dev);
 void msm_isp_sof_notify(struct vfe_device *vfe_dev,
-	enum msm_vfe_input_src frame_src, struct timeval *tv);
+	enum msm_vfe_input_src frame_src, struct msm_isp_timestamp *ts);
 void msm_isp_process_axi_irq(struct vfe_device *vfe_dev,
 	uint32_t irq_status0, uint32_t irq_status1,
-	struct timeval *tv);
+	struct msm_isp_timestamp *ts);
 #endif /* __MSM_ISP_AXI_UTIL_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
index bf348d0..17dcd0b 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
@@ -58,7 +58,7 @@
 
 void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
 	uint32_t irq_status0, uint32_t irq_status1,
-	struct timeval *tv)
+	struct msm_isp_timestamp *ts)
 {
 	int i;
 	struct msm_isp_event_data buf_event;
@@ -98,12 +98,15 @@
 				done_buf->buf_idx;
 			vfe_dev->buf_mgr->ops->buf_divert(vfe_dev->buf_mgr,
 				done_buf->bufq_handle, done_buf->buf_idx,
-				tv, 0);
+				&ts->buf_time, vfe_dev->axi_data.
+				src_info[VFE_PIX_0].frame_id);
 		}
 	}
 
 	if (stats_event->stats_mask) {
-		buf_event.timestamp = *tv;
+		buf_event.timestamp = ts->event_time;
+		buf_event.frame_id =
+			vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
 		msm_isp_send_event(vfe_dev, ISP_EVENT_STATS_NOTIFY, &buf_event);
 	}
 }
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
index 2f51b7b..13e1fd6 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.h
@@ -17,7 +17,7 @@
 
 void msm_isp_process_stats_irq(struct vfe_device *vfe_dev,
 	uint32_t irq_status0, uint32_t irq_status1,
-	struct timeval *tv);
+	struct msm_isp_timestamp *ts);
 int msm_isp_cfg_stats_stream(struct vfe_device *vfe_dev, void *arg);
 int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg);
 int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index e181b53..2a4b2d8 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -20,13 +20,13 @@
 
 #define MAX_ISP_V4l2_EVENTS 100
 
-void msm_isp_gettimeofday(struct timeval *tv)
+static inline void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp)
 {
 	struct timespec ts;
-
 	ktime_get_ts(&ts);
-	tv->tv_sec = ts.tv_sec;
-	tv->tv_usec = ts.tv_nsec/1000;
+	time_stamp->buf_time.tv_sec = ts.tv_sec;
+	time_stamp->buf_time.tv_usec = ts.tv_nsec/1000;
+	do_gettimeofday(&(time_stamp->event_time));
 }
 
 int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
@@ -504,7 +504,7 @@
 	}
 	queue_cmd->vfeInterruptStatus0 = irq_status0;
 	queue_cmd->vfeInterruptStatus1 = irq_status1;
-	msm_isp_gettimeofday(&queue_cmd->tv);
+	msm_isp_get_timestamp(&queue_cmd->ts);
 	queue_cmd->cmd_used = 1;
 	vfe_dev->taskletq_idx =
 		(vfe_dev->taskletq_idx + 1) % MSM_VFE_TASKLETQ_SIZE;
@@ -520,7 +520,7 @@
 	struct vfe_device *vfe_dev = (struct vfe_device *) data;
 	struct msm_vfe_irq_ops *irq_ops = &vfe_dev->hw_info->vfe_ops.irq_ops;
 	struct msm_vfe_tasklet_queue_cmd *queue_cmd;
-	struct timeval tv;
+	struct msm_isp_timestamp ts;
 	uint32_t irq_status0, irq_status1;
 	while (atomic_read(&vfe_dev->irq_cnt)) {
 		spin_lock_irqsave(&vfe_dev->tasklet_lock, flags);
@@ -536,7 +536,7 @@
 		queue_cmd->cmd_used = 0;
 		irq_status0 = queue_cmd->vfeInterruptStatus0;
 		irq_status1 = queue_cmd->vfeInterruptStatus1;
-		tv = queue_cmd->tv;
+		ts = queue_cmd->ts;
 		spin_unlock_irqrestore(&vfe_dev->tasklet_lock, flags);
 		ISP_DBG("%s: status0: 0x%x status1: 0x%x\n",
 			__func__, irq_status0, irq_status1);
@@ -545,13 +545,13 @@
 		irq_ops->process_halt_irq(vfe_dev,
 			irq_status0, irq_status1);
 		irq_ops->process_camif_irq(vfe_dev,
-			irq_status0, irq_status1, &tv);
+			irq_status0, irq_status1, &ts);
 		irq_ops->process_axi_irq(vfe_dev,
-			irq_status0, irq_status1, &tv);
+			irq_status0, irq_status1, &ts);
 		irq_ops->process_stats_irq(vfe_dev,
-			irq_status0, irq_status1, &tv);
+			irq_status0, irq_status1, &ts);
 		irq_ops->process_reg_update(vfe_dev,
-			irq_status0, irq_status1, &tv);
+			irq_status0, irq_status1, &ts);
 		msm_isp_process_error_info(vfe_dev);
 	}
 }
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
index 6c2a88c..3dac7e0 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
@@ -22,8 +22,6 @@
 #define ISP_DBG(fmt, args...) pr_debug(fmt, ##args)
 #endif
 
-void msm_isp_gettimeofday(struct timeval *tv);
-
 int msm_isp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
 	struct v4l2_event_subscription *sub);
 
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index c9d3f15..26ad185 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -324,7 +324,7 @@
 };
 
 struct msm_isp_event_data {
-	struct timeval timestamp;
+	struct timeval timestamp; /*Wall clock*/
 	/* if pix is a src frame_id is from camif */
 	uint32_t frame_id;
 	union {