Ver código fonte

Merge "msm: camera: isp: Notify CRM to pause SOF timer after flush" into camera-kernel.lnx.1.0

Camera Software Integration 5 anos atrás
pai
commit
f697ab3bb5

+ 9 - 0
drivers/cam_isp/cam_isp_context.c

@@ -2165,6 +2165,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
 	struct cam_hw_stop_args           stop_args;
 	struct cam_hw_reset_args          reset_args;
 	struct cam_hw_cmd_args            hw_cmd_args;
+	struct cam_req_mgr_timer_notify    timer;
 
 	ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
 
@@ -2210,6 +2211,14 @@ static int __cam_isp_ctx_flush_req_in_top_state(
 
 		CAM_INFO(CAM_ISP, "Stop HW complete. Reset HW next.");
 		CAM_DBG(CAM_ISP, "Flush wait and active lists");
+
+		if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_timer) {
+			timer.link_hdl = ctx->link_hdl;
+			timer.dev_hdl = ctx->dev_hdl;
+			timer.state = false;
+			ctx->ctx_crm_intf->notify_timer(&timer);
+		}
+
 		spin_lock_bh(&ctx->lock);
 		if (!list_empty(&ctx->wait_req_list))
 			rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,

+ 55 - 0
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -1744,6 +1744,10 @@ static void __cam_req_mgr_sof_freeze(struct timer_list *timer_data)
 	}
 
 	link = (struct cam_req_mgr_core_link *)timer->parent;
+
+	if (link->watchdog->pause_timer)
+		return;
+
 	task = cam_req_mgr_workq_get_task(link->workq);
 	if (!task) {
 		CAM_ERR(CAM_CRM, "No empty task");
@@ -2643,6 +2647,52 @@ end:
 	return rc;
 }
 
+/**
+ * cam_req_mgr_cb_notify_timer()
+ *
+ * @brief      : Notify SOF timer to pause after flush
+ * @timer_data : contains information about frame_id, link etc.
+ *
+ * @return  : 0 on success
+ *
+ */
+static int cam_req_mgr_cb_notify_timer(
+	struct cam_req_mgr_timer_notify *timer_data)
+{
+	int                              rc = 0;
+	struct cam_req_mgr_core_link    *link = NULL;
+
+	if (!timer_data) {
+		CAM_ERR(CAM_CRM, "timer data  is NULL");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	link = (struct cam_req_mgr_core_link *)
+		cam_get_device_priv(timer_data->link_hdl);
+	if (!link) {
+		CAM_DBG(CAM_CRM, "link ptr NULL %x", timer_data->link_hdl);
+		rc = -EINVAL;
+		goto end;
+	}
+
+	spin_lock_bh(&link->link_state_spin_lock);
+	if (link->state < CAM_CRM_LINK_STATE_READY) {
+		CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
+		spin_unlock_bh(&link->link_state_spin_lock);
+		rc = -EPERM;
+		goto end;
+	}
+	spin_unlock_bh(&link->link_state_spin_lock);
+
+
+	if (!timer_data->state)
+		link->watchdog->pause_timer = true;
+
+end:
+	return rc;
+}
+
 /**
  * cam_req_mgr_cb_notify_trigger()
  *
@@ -2682,6 +2732,10 @@ static int cam_req_mgr_cb_notify_trigger(
 		rc = -EPERM;
 		goto end;
 	}
+
+	if (link->watchdog->pause_timer)
+		link->watchdog->pause_timer = false;
+
 	crm_timer_reset(link->watchdog);
 	spin_unlock_bh(&link->link_state_spin_lock);
 
@@ -2711,6 +2765,7 @@ static struct cam_req_mgr_crm_cb cam_req_mgr_ops = {
 	.notify_trigger = cam_req_mgr_cb_notify_trigger,
 	.notify_err     = cam_req_mgr_cb_notify_err,
 	.add_req        = cam_req_mgr_cb_add_req,
+	.notify_timer   = cam_req_mgr_cb_notify_timer,
 };
 
 /**

+ 16 - 0
drivers/cam_req_mgr/cam_req_mgr_interface.h

@@ -14,6 +14,7 @@
 struct cam_req_mgr_trigger_notify;
 struct cam_req_mgr_error_notify;
 struct cam_req_mgr_add_request;
+struct cam_req_mgr_timer_notify;
 struct cam_req_mgr_device_info;
 struct cam_req_mgr_core_dev_link_setup;
 struct cam_req_mgr_apply_request;
@@ -35,6 +36,7 @@ typedef int (*cam_req_mgr_notify_trigger)(
 	struct cam_req_mgr_trigger_notify *);
 typedef int (*cam_req_mgr_notify_err)(struct cam_req_mgr_error_notify *);
 typedef int (*cam_req_mgr_add_req)(struct cam_req_mgr_add_request *);
+typedef int (*cam_req_mgr_notify_timer)(struct cam_req_mgr_timer_notify *);
 
 /**
  * @brief: cam req mgr to camera device drivers
@@ -64,6 +66,7 @@ struct cam_req_mgr_crm_cb {
 	cam_req_mgr_notify_trigger  notify_trigger;
 	cam_req_mgr_notify_err      notify_err;
 	cam_req_mgr_add_req         add_req;
+	cam_req_mgr_notify_timer    notify_timer;
 };
 
 /**
@@ -206,6 +209,19 @@ struct cam_req_mgr_trigger_notify {
 	uint64_t sof_timestamp_val;
 };
 
+/**
+ * struct cam_req_mgr_timer_notify
+ * @link_hdl : link identifier
+ * @dev_hdl  : device handle which has sent this req id
+ * @frame_id : frame id for internal tracking
+ * @state    : timer state i.e ON or OFF
+ */
+struct cam_req_mgr_timer_notify {
+	int32_t  link_hdl;
+	int32_t  dev_hdl;
+	bool     state;
+};
+
 /**
  * struct cam_req_mgr_error_notify
  * @link_hdl : link identifier

+ 7 - 5
drivers/cam_req_mgr/cam_req_mgr_timer.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_REQ_MGR_TIMER_H_
@@ -12,16 +12,18 @@
 #include "cam_req_mgr_core_defs.h"
 
 /** struct cam_req_mgr_timer
- * @expires   : timeout value for timer
- * @sys_timer : system timer variable
- * @parent    : priv data - link pointer
- * @timer_cb  : callback func which will be called when timeout expires
+ * @expires      : timeout value for timer
+ * @sys_timer    : system timer variable
+ * @parent       : priv data - link pointer
+ * @timer_cb     : callback func which will be called when timeout expires
+ * @pause_timer  : flag to pause SOF timer
  */
 struct cam_req_mgr_timer {
 	int32_t            expires;
 	struct timer_list  sys_timer;
 	void               *parent;
 	void               (*timer_cb)(struct timer_list *timer_data);
+	bool                pause_timer;
 };
 
 /**