diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index b251d75ac2..1a66070585 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/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, diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index faa15479ec..00677b9d86 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/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, }; /** diff --git a/drivers/cam_req_mgr/cam_req_mgr_interface.h b/drivers/cam_req_mgr/cam_req_mgr_interface.h index f4b662dd41..5df13b26e2 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_interface.h +++ b/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 diff --git a/drivers/cam_req_mgr/cam_req_mgr_timer.h b/drivers/cam_req_mgr/cam_req_mgr_timer.h index 9f9ba71a38..be200f1b26 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_timer.h +++ b/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; }; /**