Merge "msm: cpp: Ignore hardware interrupt when timer expires"
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 4dd8e5f..61c51a6 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -634,15 +634,17 @@
 			if (tx_fifo[i] == MSM_CPP_MSG_ID_CMD) {
 				cmd_len = tx_fifo[i+1];
 				msg_id = tx_fifo[i+2];
-				if (msg_id == MSM_CPP_MSG_ID_FRAME_ACK) {
+				if ((msg_id == MSM_CPP_MSG_ID_FRAME_ACK)
+					&& (atomic_read(&cpp_timer.used))) {
 					CPP_DBG("Frame done!!\n");
 					/* delete CPP timer */
 					CPP_DBG("delete timer.\n");
 					msm_cpp_clear_timer(cpp_dev);
 					msm_cpp_notify_frame_done(cpp_dev,
 						VIDIOC_MSM_BUF_MNGR_BUF_DONE);
-				} else if (msg_id ==
-					MSM_CPP_MSG_ID_FRAME_NACK) {
+				} else if ((msg_id ==
+					MSM_CPP_MSG_ID_FRAME_NACK)
+					&& (atomic_read(&cpp_timer.used))) {
 					pr_err("NACK error from hw!!\n");
 					CPP_DBG("delete timer.\n");
 					msm_cpp_clear_timer(cpp_dev);
@@ -1184,7 +1186,13 @@
 
 	disable_irq(cpp_timer.data.cpp_dev->irq->start);
 	pr_err("Reloading firmware\n");
-	cpp_load_fw(cpp_timer.data.cpp_dev, NULL);
+	if (!atomic_read(&cpp_timer.used)) {
+		pr_err("Delayed trigger, IRQ serviced\n");
+		return;
+	}
+	atomic_set(&cpp_timer.used, 0);
+	cpp_load_fw(cpp_timer.data.cpp_dev,
+		cpp_timer.data.cpp_dev->fw_name_bin);
 	pr_err("Firmware loading done\n");
 	enable_irq(cpp_timer.data.cpp_dev->irq->start);
 	msm_camera_io_w_mb(0x8, cpp_timer.data.cpp_dev->base +
@@ -1193,11 +1201,6 @@
 		cpp_timer.data.cpp_dev->base +
 		MSM_CPP_MICRO_IRQGEN_CLR);
 
-	if (!atomic_read(&cpp_timer.used)) {
-		pr_err("Delayed trigger, IRQ serviced\n");
-		return;
-	}
-
 	if (cpp_timer.data.cpp_dev->timeout_trial_cnt >=
 		MSM_CPP_MAX_TIMEOUT_TRIAL) {
 		pr_info("Max trial reached\n");
@@ -1536,8 +1539,8 @@
 		return -EINVAL;
 	}
 
-	if ((ioctl_ptr->ioctl_ptr == NULL) || (ioctl_ptr->len == 0)){
-		pr_err("ioctl_ptr OR ioctl_ptr->len is NULL  %p %d \n",
+	if ((ioctl_ptr->ioctl_ptr == NULL) || (ioctl_ptr->len == 0)) {
+		pr_err("ioctl_ptr OR ioctl_ptr->len is NULL  %p %d\n",
 			ioctl_ptr, ioctl_ptr->len);
 		return -EINVAL;
 	}
@@ -1562,7 +1565,7 @@
 				cpp_dev->fw_name_bin = NULL;
 			}
 			if (ioctl_ptr->len >= MSM_CPP_MAX_FW_NAME_LEN) {
-				pr_err("Error: ioctl_ptr->len = %d \n",
+				pr_err("Error: ioctl_ptr->len = %d\n",
 					 ioctl_ptr->len);
 				mutex_unlock(&cpp_dev->mutex);
 				return -EINVAL;
@@ -1749,7 +1752,7 @@
 		struct msm_queue_cmd *event_qcmd;
 		struct msm_cpp_frame_info_t *process_frame;
 		event_qcmd = msm_dequeue(queue, list_eventdata);
-		if(event_qcmd) {
+		if (event_qcmd) {
 			process_frame = event_qcmd->command;
 			CPP_DBG("fid %d\n", process_frame->frame_id);
 			if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
@@ -1766,8 +1769,11 @@
 			}
 
 			kfree(process_frame->cpp_cmd_msg);
+			process_frame->cpp_cmd_msg = NULL;
 			kfree(process_frame);
+			process_frame = NULL;
 			kfree(event_qcmd);
+			event_qcmd = NULL;
 		} else {
 			pr_err("Empty command list\n");
 			return -EFAULT;