diff options
author | Roger Liao <rogerliao@google.com> | 2020-06-24 18:42:15 +0800 |
---|---|---|
committer | Roger Liao <rogerliao@google.com> | 2020-06-24 18:42:40 +0800 |
commit | 4b51c72f2a9611bab9651a74f7870bc9feb927e7 (patch) | |
tree | 5eb58a70473d659ba795e9f1752739933e2e62c9 | |
parent | f0f7c32d0800f4bbcefbcd440357d330fe446752 (diff) | |
parent | 7ff66257f6ff63d1d4b2df2f592d55bf3c0c918f (diff) | |
download | camera-kernel-4b51c72f2a9611bab9651a74f7870bc9feb927e7.tar.gz |
Merge branch 'android-msm-pixel-4.19' into android-msm-barbet-4.19
Merge from build 6619817
Align to LA.UM.9.12.R2.10.00.00.685.014
Bug: 159778850
Signed-off-by: Roger Liao <rogerliao@google.com>
Change-Id: Ic143c789c5f2326ae880c5a88bb3f479b4014909
23 files changed, 481 insertions, 38 deletions
diff --git a/drivers/cam_cdm/cam_cdm.h b/drivers/cam_cdm/cam_cdm.h index c20e0d6..54882fb 100644 --- a/drivers/cam_cdm/cam_cdm.h +++ b/drivers/cam_cdm/cam_cdm.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_CDM_H_ @@ -52,6 +52,7 @@ enum cam_cdm_hw_process_intf_cmd { CAM_CDM_HW_INTF_CMD_RELEASE, CAM_CDM_HW_INTF_CMD_SUBMIT_BL, CAM_CDM_HW_INTF_CMD_RESET_HW, + CAM_CDM_HW_INTF_CMD_HANG_DETECT, CAM_CDM_HW_INTF_CMD_INVALID, }; @@ -217,6 +218,7 @@ struct cam_cdm { atomic_t bl_done; struct cam_cdm_hw_mem gen_irq; uint32_t cpas_handle; + atomic_t work_record; }; /* struct cam_cdm_private_dt_data - CDM hw custom dt data */ diff --git a/drivers/cam_cdm/cam_cdm_core_common.c b/drivers/cam_cdm/cam_cdm_core_common.c index e903dc8..ee9f494 100644 --- a/drivers/cam_cdm/cam_cdm_core_common.c +++ b/drivers/cam_cdm/cam_cdm_core_common.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include <linux/delay.h> @@ -579,6 +579,31 @@ int cam_cdm_process_cmd(void *hw_priv, *((uint32_t *)cmd_args)); break; } + case CAM_CDM_HW_INTF_CMD_HANG_DETECT: { + uint32_t *handle = cmd_args; + int idx; + struct cam_cdm_client *client; + + if (sizeof(uint32_t) != arg_size) { + CAM_ERR(CAM_CDM, + "Invalid CDM cmd %d size=%x for handle=%x", + cmd, arg_size, *handle); + return -EINVAL; + } + + idx = CAM_CDM_GET_CLIENT_IDX(*handle); + mutex_lock(&cdm_hw->hw_mutex); + client = core->clients[idx]; + if ((!client) || (*handle != client->handle)) { + CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", + client, *handle); + mutex_unlock(&cdm_hw->hw_mutex); + break; + } + rc = cam_hw_cdm_hang_detect(cdm_hw, *handle); + mutex_unlock(&cdm_hw->hw_mutex); + break; + } default: CAM_ERR(CAM_CDM, "CDM HW intf command not valid =%d", cmd); break; diff --git a/drivers/cam_cdm/cam_cdm_core_common.h b/drivers/cam_cdm/cam_cdm_core_common.h index 8dcbe8e..64dc52d 100644 --- a/drivers/cam_cdm/cam_cdm_core_common.h +++ b/drivers/cam_cdm/cam_cdm_core_common.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_CDM_CORE_COMMON_H_ @@ -37,6 +37,7 @@ int cam_virtual_cdm_submit_bl(struct cam_hw_info *cdm_hw, int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw, struct cam_cdm_hw_intf_cmd_submit_bl *req, struct cam_cdm_client *client); +int cam_hw_cdm_hang_detect(struct cam_hw_info *cdm_hw, uint32_t handle); struct cam_cdm_bl_cb_request_entry *cam_cdm_find_request_by_bl_tag( uint32_t tag, struct list_head *bl_list); void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw, diff --git a/drivers/cam_cdm/cam_cdm_hw_core.c b/drivers/cam_cdm/cam_cdm_hw_core.c index 92f30ec..f68c393 100644 --- a/drivers/cam_cdm/cam_cdm_hw_core.c +++ b/drivers/cam_cdm/cam_cdm_hw_core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include <linux/delay.h> @@ -563,6 +563,10 @@ static void cam_hw_cdm_work(struct work_struct *work) CAM_DBG(CAM_CDM, "inline IRQ data=0x%x", payload->irq_data); mutex_lock(&cdm_hw->hw_mutex); + + if (atomic_read(&core->work_record)) + atomic_dec(&core->work_record); + list_for_each_entry_safe(node, tnode, &core->bl_request_list, entry) { if (node->request_type == @@ -689,6 +693,9 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) payload->hw = cdm_hw; INIT_WORK((struct work_struct *)&payload->work, cam_hw_cdm_work); + if (payload->irq_status & + CAM_CDM_IRQ_STATUS_INFO_INLINE_IRQ_MASK) + atomic_inc(&cdm_core->work_record); work_status = queue_work(cdm_core->work_queue, &payload->work); if (work_status == false) { CAM_ERR(CAM_CDM, "Failed to queue work for irq=0x%x", @@ -700,6 +707,22 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data) return IRQ_HANDLED; } +int cam_hw_cdm_hang_detect(struct cam_hw_info *cdm_hw, uint32_t handle) +{ + struct cam_cdm *cdm_core = NULL; + int rc = -1; + + cdm_core = (struct cam_cdm *)cdm_hw->core_info; + + if (atomic_read(&cdm_core->work_record)) { + CAM_WARN(CAM_CDM, + "workqueue got delayed, work_record :%u", + atomic_read(&cdm_core->work_record)); + rc = 0; + } + return rc; +} + int cam_hw_cdm_alloc_genirq_mem(void *hw_priv) { struct cam_hw_info *cdm_hw = hw_priv; @@ -775,6 +798,7 @@ int cam_hw_cdm_init(void *hw_priv, CAM_DBG(CAM_CDM, "Enable soc done"); /* Before triggering the reset to HW, clear the reset complete */ + atomic_set(&cdm_core->work_record, 0); atomic_set(&cdm_core->error, 0); atomic_set(&cdm_core->bl_done, 0); reinit_completion(&cdm_core->reset_complete); @@ -824,6 +848,7 @@ int cam_hw_cdm_deinit(void *hw_priv, soc_info = &cdm_hw->soc_info; cdm_core = cdm_hw->core_info; + atomic_set(&cdm_core->work_record, 0); rc = cam_soc_util_disable_platform_resource(soc_info, true, true); if (rc) { CAM_ERR(CAM_CDM, "disable platform failed"); @@ -888,6 +913,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev) cdm_core->flags = CAM_CDM_FLAG_PRIVATE_CDM; cdm_core->bl_tag = 0; + atomic_set(&cdm_core->work_record, 0); cdm_core->id = cam_hw_cdm_get_id_by_name(cdm_core->name); if (cdm_core->id >= CAM_CDM_MAX) { CAM_ERR(CAM_CDM, "Failed to get CDM HW name for %s", diff --git a/drivers/cam_cdm/cam_cdm_intf.c b/drivers/cam_cdm/cam_cdm_intf.c index 7694463..599991e 100644 --- a/drivers/cam_cdm/cam_cdm_intf.c +++ b/drivers/cam_cdm/cam_cdm_intf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include <linux/delay.h> @@ -379,6 +379,33 @@ int cam_cdm_reset_hw(uint32_t handle) } EXPORT_SYMBOL(cam_cdm_reset_hw); +int cam_cdm_detect_hang_error(uint32_t handle) +{ + uint32_t hw_index; + int rc = -EINVAL; + struct cam_hw_intf *hw; + + if (get_cdm_mgr_refcount()) { + CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed"); + rc = -EPERM; + return rc; + } + + hw_index = CAM_CDM_GET_HW_IDX(handle); + if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) { + hw = cdm_mgr.nodes[hw_index].device; + if (hw && hw->hw_ops.process_cmd) + rc = hw->hw_ops.process_cmd(hw->hw_priv, + CAM_CDM_HW_INTF_CMD_HANG_DETECT, + &handle, + sizeof(handle)); + } + put_cdm_mgr_refcount(); + + return rc; +} +EXPORT_SYMBOL(cam_cdm_detect_hang_error); + int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw, struct cam_cdm_private_dt_data *data, enum cam_cdm_type type, uint32_t *index) diff --git a/drivers/cam_cdm/cam_cdm_intf_api.h b/drivers/cam_cdm/cam_cdm_intf_api.h index 3e89b22..466ead3 100644 --- a/drivers/cam_cdm/cam_cdm_intf_api.h +++ b/drivers/cam_cdm/cam_cdm_intf_api.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_CDM_API_H_ @@ -199,4 +199,13 @@ int cam_cdm_stream_off(uint32_t handle); */ int cam_cdm_reset_hw(uint32_t handle); +/** + * @brief : API to detect hang in previously acquired CDM, + * this should be only performed only if the CDM is private. + * + * @handle : Input handle of the CDM to detect hang + * + * @return 0 on success + */ +int cam_cdm_detect_hang_error(uint32_t handle); #endif /* _CAM_CDM_API_H_ */ diff --git a/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c index 88dd757..6e61e33 100644 --- a/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c +++ b/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c @@ -1587,7 +1587,7 @@ static int cam_fd_mgr_hw_dump( return rc; hw_dump: cur_time = ktime_get(); - diff = ktime_us_delta(frame_req->submit_timestamp, cur_time); + diff = ktime_us_delta(cur_time, frame_req->submit_timestamp); cur_ts = ktime_to_timespec64(cur_time); req_ts = ktime_to_timespec64(frame_req->submit_timestamp); if (diff < CAM_FD_RESPONSE_TIME_THRESHOLD) { diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 3df1194..f76a6da 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -5225,7 +5225,7 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args) return 0; hw_dump: cur_time = ktime_get(); - diff = ktime_us_delta(frm_process->submit_timestamp[i], cur_time); + diff = ktime_us_delta(cur_time, frm_process->submit_timestamp[i]); cur_ts = ktime_to_timespec64(cur_time); req_ts = ktime_to_timespec64(frm_process->submit_timestamp[i]); diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 0edea5b..b8608ee 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -2769,9 +2769,8 @@ hw_dump: ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; req_isp = (struct cam_isp_ctx_req *) req->req_priv; cur_time = ktime_get(); - diff = ktime_us_delta( - req_isp->event_timestamp[CAM_ISP_CTX_EVENT_APPLY], - cur_time); + diff = ktime_us_delta(cur_time, + req_isp->event_timestamp[CAM_ISP_CTX_EVENT_APPLY]); if (diff < CAM_ISP_CTX_RESPONSE_TIME_THRESHOLD) { CAM_INFO(CAM_ISP, "req %lld found no error", req->request_id); @@ -4662,7 +4661,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, ctx->state = CAM_CTX_READY; trace_cam_context_state("ISP", ctx); if (rc == -ETIMEDOUT) - rc = cam_isp_ctx_dump_req(req_isp, 0, 0, NULL, false); + cam_isp_ctx_dump_req(req_isp, 0, 0, NULL, false); list_del_init(&req->list); list_add(&req->list, &ctx->pending_req_list); goto end; diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index aaffdbc..9ec7636 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -25,6 +25,7 @@ #include "cam_common_util.h" #define CAM_IFE_HW_ENTRIES_MAX 20 +#define CAM_IFE_HW_CONFIG_WAIT_MAX_TRY 3 #define TZ_SVC_SMMU_PROGRAM 0x15 #define TZ_SAFE_SYSCALL_ID 0x3 @@ -824,6 +825,47 @@ static void cam_ife_hw_mgr_dump_acq_data( } } +static int cam_ife_mgr_csid_change_halt_mode(struct list_head *halt_list, + uint32_t base_idx, enum cam_ife_csid_halt_mode halt_mode) +{ + struct cam_ife_hw_mgr_res *hw_mgr_res; + struct cam_isp_resource_node *isp_res; + struct cam_csid_hw_halt_args halt; + struct cam_hw_intf *hw_intf; + uint32_t i; + int rc = 0; + + list_for_each_entry(hw_mgr_res, halt_list, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i] || + (hw_mgr_res->hw_res[i]->res_state != + CAM_ISP_RESOURCE_STATE_STREAMING)) + continue; + + isp_res = hw_mgr_res->hw_res[i]; + if (isp_res->hw_intf->hw_idx != base_idx) + continue; + + if ((isp_res->res_type == CAM_ISP_RESOURCE_PIX_PATH) && + (isp_res->res_id == CAM_IFE_PIX_PATH_RES_IPP)) { + hw_intf = isp_res->hw_intf; + halt.node_res = isp_res; + halt.halt_mode = halt_mode; + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE, + &halt, + sizeof(struct cam_csid_hw_halt_args)); + if (rc) + CAM_ERR(CAM_ISP, "Halt update failed"); + break; + } + } + } + + return rc; +} + static int cam_ife_mgr_csid_stop_hw( struct cam_ife_hw_mgr_ctx *ctx, struct list_head *stop_list, uint32_t base_idx, uint32_t stop_cmd) @@ -871,6 +913,10 @@ static int cam_ife_hw_mgr_release_hw_for_ctx( struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_ife_hw_mgr_res *hw_mgr_res_temp; + /* clean up the callback function */ + ife_ctx->common.cb_priv = NULL; + memset(ife_ctx->common.event_cb, 0, sizeof(ife_ctx->common.event_cb)); + /* ife leaf resource */ for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) cam_ife_hw_mgr_free_hw_res(&ife_ctx->res_list_ife_out[i]); @@ -907,10 +953,6 @@ static int cam_ife_hw_mgr_release_hw_for_ctx( if (ife_ctx->res_list_ife_in.res_type != CAM_IFE_HW_MGR_RES_UNINIT) cam_ife_hw_mgr_free_hw_res(&ife_ctx->res_list_ife_in); - /* clean up the callback function */ - ife_ctx->common.cb_priv = NULL; - memset(ife_ctx->common.event_cb, 0, sizeof(ife_ctx->common.event_cb)); - CAM_DBG(CAM_ISP, "release context completed ctx id:%d", ife_ctx->ctx_index); @@ -1524,6 +1566,16 @@ static int cam_ife_hw_mgr_acquire_csid_hw( if (!ife_hw_mgr->csid_devices[i]) continue; + if (csid_acquire->in_port->dsp_mode) { + rc = ife_hw_mgr->ife_devices[i]->hw_ops + .process_cmd( + ife_hw_mgr->ife_devices[i]->hw_priv, + CAM_ISP_HW_CMD_QUERY_DSP_MODE, + NULL, 0); + if (rc) + continue; + } + hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, csid_acquire, @@ -1539,6 +1591,15 @@ static int cam_ife_hw_mgr_acquire_csid_hw( if (!ife_hw_mgr->csid_devices[i]) continue; + if (csid_acquire->in_port->dsp_mode) { + rc = ife_hw_mgr->ife_devices[i]->hw_ops.process_cmd( + ife_hw_mgr->ife_devices[i]->hw_priv, + CAM_ISP_HW_CMD_QUERY_DSP_MODE, + NULL, 0); + if (rc) + continue; + } + hw_intf = ife_hw_mgr->csid_devices[i]; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, csid_acquire, @@ -1999,18 +2060,36 @@ err: static int cam_ife_mgr_check_and_update_fe_v0( struct cam_ife_hw_mgr_ctx *ife_ctx, - struct cam_isp_acquire_hw_info *acquire_hw_info) + struct cam_isp_acquire_hw_info *acquire_hw_info, + uint32_t acquire_info_size) { int i; struct cam_isp_in_port_info *in_port = NULL; uint32_t in_port_length = 0; uint32_t total_in_port_length = 0; + if (acquire_hw_info->input_info_offset >= + acquire_hw_info->input_info_size) { + CAM_ERR(CAM_ISP, + "Invalid size offset 0x%x is greater then size 0x%x", + acquire_hw_info->input_info_offset, + acquire_hw_info->input_info_size); + return -EINVAL; + } + in_port = (struct cam_isp_in_port_info *) ((uint8_t *)&acquire_hw_info->data + acquire_hw_info->input_info_offset); for (i = 0; i < acquire_hw_info->num_inputs; i++) { + if (((uint8_t *)in_port + + sizeof(struct cam_isp_in_port_info)) > + ((uint8_t *)acquire_hw_info + + acquire_info_size)) { + CAM_ERR(CAM_ISP, "Invalid size"); + return -EINVAL; + } + if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) || (in_port->num_out_res <= 0)) { CAM_ERR(CAM_ISP, "Invalid num output res %u", @@ -2044,18 +2123,36 @@ static int cam_ife_mgr_check_and_update_fe_v0( static int cam_ife_mgr_check_and_update_fe_v2( struct cam_ife_hw_mgr_ctx *ife_ctx, - struct cam_isp_acquire_hw_info *acquire_hw_info) + struct cam_isp_acquire_hw_info *acquire_hw_info, + uint32_t acquire_info_size) { int i; struct cam_isp_in_port_info_v2 *in_port = NULL; uint32_t in_port_length = 0; uint32_t total_in_port_length = 0; + if (acquire_hw_info->input_info_offset >= + acquire_hw_info->input_info_size) { + CAM_ERR(CAM_ISP, + "Invalid size offset 0x%x is greater then size 0x%x", + acquire_hw_info->input_info_offset, + acquire_hw_info->input_info_size); + return -EINVAL; + } + in_port = (struct cam_isp_in_port_info_v2 *) ((uint8_t *)&acquire_hw_info->data + acquire_hw_info->input_info_offset); for (i = 0; i < acquire_hw_info->num_inputs; i++) { + if (((uint8_t *)in_port + + sizeof(struct cam_isp_in_port_info)) > + ((uint8_t *)acquire_hw_info + + acquire_info_size)) { + CAM_ERR(CAM_ISP, "Invalid size"); + return -EINVAL; + } + if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) || (in_port->num_out_res <= 0)) { CAM_ERR(CAM_ISP, "Invalid num output res %u", @@ -2092,7 +2189,8 @@ static int cam_ife_mgr_check_and_update_fe_v2( static int cam_ife_mgr_check_and_update_fe( struct cam_ife_hw_mgr_ctx *ife_ctx, - struct cam_isp_acquire_hw_info *acquire_hw_info) + struct cam_isp_acquire_hw_info *acquire_hw_info, + uint32_t acquire_info_size) { uint32_t major_ver = 0, minor_ver = 0; @@ -2105,10 +2203,10 @@ static int cam_ife_mgr_check_and_update_fe( switch (major_ver) { case 1: return cam_ife_mgr_check_and_update_fe_v0( - ife_ctx, acquire_hw_info); + ife_ctx, acquire_hw_info, acquire_info_size); case 2: return cam_ife_mgr_check_and_update_fe_v2( - ife_ctx, acquire_hw_info); + ife_ctx, acquire_hw_info, acquire_info_size); break; default: CAM_ERR(CAM_ISP, "Invalid ver of common info from user"); @@ -2906,7 +3004,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) acquire_hw_info = (struct cam_isp_acquire_hw_info *)acquire_args->acquire_info; - rc = cam_ife_mgr_check_and_update_fe(ife_ctx, acquire_hw_info); + rc = cam_ife_mgr_check_and_update_fe(ife_ctx, acquire_hw_info, + acquire_args->acquire_info_size); if (rc) { CAM_ERR(CAM_ISP, "buffer size is not enough"); goto free_cdm; @@ -3659,23 +3758,45 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv, return rc; } - if (cfg->init_packet) { + if (!cfg->init_packet) + goto end; + + for (i = 0; i < CAM_IFE_HW_CONFIG_WAIT_MAX_TRY; i++) { rem_jiffies = wait_for_completion_timeout( &ctx->config_done_complete, msecs_to_jiffies(30)); if (rem_jiffies == 0) { + if (!cam_cdm_detect_hang_error( + ctx->cdm_handle)) { + CAM_INFO(CAM_ISP, + "CDM workqueue delay detected, wait for some more time req_id=%llu rc=%d ctx_index %d", + cfg->request_id, rc, + ctx->ctx_index); + continue; + } CAM_ERR(CAM_ISP, "config done completion timeout for req_id=%llu ctx_index %d", cfg->request_id, ctx->ctx_index); rc = -ETIMEDOUT; - } else + goto end; + } else { + rc = 0; CAM_DBG(CAM_ISP, "config done Success for req_id=%llu ctx_index %d", cfg->request_id, ctx->ctx_index); + break; + } + } + if ((i == CAM_IFE_HW_CONFIG_WAIT_MAX_TRY) && (rc == 0)) { + CAM_ERR(CAM_ISP, + "config done completion timeout for req_id=%llu ctx_index %d", + cfg->request_id, ctx->ctx_index); + rc = -ETIMEDOUT; } } else { CAM_ERR(CAM_ISP, "No commands to config"); } +end: CAM_DBG(CAM_ISP, "Exit: Config Done: %llu", cfg->request_id); return rc; @@ -3865,6 +3986,19 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) */ if (i == ctx->num_base) master_base_idx = ctx->base[0].idx; + + /*Change slave mode*/ + if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY) { + for (i = 0; i < ctx->num_base; i++) { + if (ctx->base[i].idx == master_base_idx) + continue; + cam_ife_mgr_csid_change_halt_mode( + &ctx->res_list_ife_csid, + ctx->base[i].idx, + CAM_CSID_HALT_MODE_INTERNAL); + } + } + CAM_DBG(CAM_ISP, "Stopping master CSID idx %d", master_base_idx); /* Stop the master CSID path first */ @@ -6820,8 +6954,13 @@ static int cam_ife_hw_mgr_find_affected_ctx( * In the call back function corresponding ISP context * will update CRM about fatal Error */ - notify_err_cb(ife_hwr_mgr_ctx->common.cb_priv, - CAM_ISP_HW_EVENT_ERROR, error_event_data); + if (notify_err_cb) { + notify_err_cb(ife_hwr_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_ERROR, error_event_data); + } else { + CAM_WARN(CAM_ISP, "Error call back is not set"); + goto end; + } } /* fill the affected_core in recovery data */ @@ -6830,7 +6969,7 @@ static int cam_ife_hw_mgr_find_affected_ctx( CAM_DBG(CAM_ISP, "Vfe core %d is affected (%d)", i, recovery_data->affected_core[i]); } - +end: return 0; } @@ -6894,6 +7033,8 @@ static int cam_ife_hw_mgr_handle_hw_err( rc = cam_ife_hw_mgr_find_affected_ctx(&error_event_data, core_idx, &recovery_data); + if ((rc != 0) || !(recovery_data.no_of_context)) + goto end; if (event_info->err_type == CAM_VFE_IRQ_STATUS_VIOLATION) recovery_data.error_type = CAM_ISP_HW_ERROR_VIOLATION; @@ -6901,8 +7042,8 @@ static int cam_ife_hw_mgr_handle_hw_err( recovery_data.error_type = CAM_ISP_HW_ERROR_OVERFLOW; cam_ife_hw_mgr_do_error_recovery(&recovery_data); +end: spin_unlock(&g_ife_hw_mgr.ctx_lock); - return rc; } @@ -6915,6 +7056,11 @@ static int cam_ife_hw_mgr_handle_hw_rup( cam_hw_event_cb_func ife_hwr_irq_rup_cb; struct cam_isp_hw_reg_update_event_data rup_event_data; + if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_REG_UPDATE]) { + CAM_ERR(CAM_ISP, "event_cb[HW_EVENT_REG_UPDATE] is null"); + return 0; + } + ife_hwr_irq_rup_cb = ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_REG_UPDATE]; @@ -6955,7 +7101,6 @@ static int cam_ife_hw_mgr_handle_hw_rup( CAM_DBG(CAM_ISP, "RUP done for VFE:%d source %d", event_info->hw_idx, event_info->res_id); - return 0; } @@ -7026,6 +7171,11 @@ static int cam_ife_hw_mgr_handle_hw_epoch( struct cam_isp_hw_epoch_event_data epoch_done_event_data; int rc = 0; + if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EPOCH]) { + CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_EPOCH] is null"); + return 0; + } + ife_hw_irq_epoch_cb = ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EPOCH]; @@ -7075,6 +7225,11 @@ static int cam_ife_hw_mgr_handle_hw_sof( struct cam_isp_hw_sof_event_data sof_done_event_data; int rc = 0; + if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_SOF]) { + CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_SOF] is null"); + return 0; + } + memset(&sof_done_event_data, 0, sizeof(sof_done_event_data)); ife_hw_irq_sof_cb = @@ -7150,6 +7305,11 @@ static int cam_ife_hw_mgr_handle_hw_eof( struct cam_isp_hw_eof_event_data eof_done_event_data; int rc = 0; + if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF]) { + CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_EOF] is null"); + return 0; + } + ife_hw_irq_eof_cb = ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF]; @@ -7195,6 +7355,11 @@ static int cam_ife_hw_mgr_handle_hw_buf_done( struct cam_isp_hw_done_event_data buf_done_event_data = {0}; struct cam_isp_hw_event_info *event_info = evt_info; + if (!ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_DONE]) { + CAM_ERR(CAM_ISP, "event_cb[CAM_ISP_HW_EVENT_DONE] is null"); + return 0; + } + ife_hwr_irq_wm_done_cb = ife_hw_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_DONE]; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 42daa02..c70ee14 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -2128,6 +2128,64 @@ static int cam_ife_csid_enable_pxl_path( return 0; } + +static void cam_ife_csid_change_pxl_halt_mode( + struct cam_ife_csid_hw *csid_hw, + struct cam_isp_resource_node *res, + enum cam_ife_csid_halt_mode halt_mode) +{ + uint32_t val = 0; + const struct cam_ife_csid_reg_offset *csid_reg; + struct cam_hw_soc_info *soc_info; + struct cam_ife_csid_path_cfg *path_data; + const struct cam_ife_csid_pxl_reg_offset *pxl_reg; + bool is_ipp; + + path_data = (struct cam_ife_csid_path_cfg *) res->res_priv; + csid_reg = csid_hw->csid_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_id >= CAM_IFE_PIX_PATH_RES_MAX) { + CAM_ERR(CAM_ISP, "CSID:%d Invalid res id%d", + csid_hw->hw_intf->hw_idx, res->res_id); + goto end; + } + + if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW || + res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) { + CAM_ERR(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d", + csid_hw->hw_intf->hw_idx, res->res_id, res->res_state); + goto end; + } + + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) { + is_ipp = true; + pxl_reg = csid_reg->ipp_reg; + } else { + goto end; + } + + if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { + CAM_ERR(CAM_ISP, "CSID:%d %s path Res:%d Invalid state%d", + csid_hw->hw_intf->hw_idx, (is_ipp) ? "IPP" : "PPP", + res->res_id, res->res_state); + goto end; + } + + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_irq_mask_addr); + + /* configure Halt for slave */ + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); + val &= ~0xC; + val |= (halt_mode << 2); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + pxl_reg->csid_pxl_ctrl_addr); +end: + return; +} + static int cam_ife_csid_disable_pxl_path( struct cam_ife_csid_hw *csid_hw, struct cam_isp_resource_node *res, @@ -3693,6 +3751,41 @@ end: return rc; } +int cam_ife_csid_halt(struct cam_ife_csid_hw *csid_hw, + void *halt_args) +{ + struct cam_isp_resource_node *res; + struct cam_csid_hw_halt_args *csid_halt; + + if (!csid_hw || !halt_args) { + CAM_ERR(CAM_ISP, "CSID: Invalid args"); + return -EINVAL; + } + + csid_halt = (struct cam_csid_hw_halt_args *)halt_args; + + /* Change the halt mode */ + res = csid_halt->node_res; + CAM_DBG(CAM_ISP, "CSID:%d res_type %d res_id %d", + csid_hw->hw_intf->hw_idx, + res->res_type, res->res_id); + + switch (res->res_type) { + case CAM_ISP_RESOURCE_PIX_PATH: + if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) + cam_ife_csid_change_pxl_halt_mode(csid_hw, res, + csid_halt->halt_mode); + break; + default: + CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d", + csid_hw->hw_intf->hw_idx, + res->res_type); + break; + } + + return 0; +} + int cam_ife_csid_stop(void *hw_priv, void *stop_args, uint32_t arg_size) { @@ -4090,6 +4183,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv, case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG: rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args); break; + case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE: + rc = cam_ife_csid_halt(csid_hw, cmd_args); + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h index 5afc0b7..498854b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h @@ -154,6 +154,33 @@ enum cam_ife_csid_halt_cmd { }; /** + * enum cam_ife_csid_halt_mode_cmd - Specify the halt command type + */ +enum cam_ife_csid_halt_mode { + CAM_CSID_HALT_MODE_INTERNAL, + CAM_CSID_HALT_MODE_GLOBAL, + CAM_CSID_HALT_MODE_MASTER, + CAM_CSID_HALT_MODE_SLAVE, + CAM_CSID_HALT_MODE_MAX, +}; + +/** + * struct cam_csid_hw_halt_args + * @halt_mode : Applicable only for PATH resources + * 0 Internal : The CSID responds to the HALT_CMD + * 1 Global : The CSID responds to the GLOBAL_HALT_CMD + * 2 Master : The CSID responds to the HALT_CMD + * 3 Slave : The CSID responds to the external halt command + * and not the HALT_CMD register + * @node_res : reource pointer array( ie cid or CSID) + * + */ +struct cam_csid_hw_halt_args { + enum cam_ife_csid_halt_mode halt_mode; + struct cam_isp_resource_node *node_res; +}; + +/** * struct cam_csid_hw_stop- stop all resources * @stop_cmd : Applicable only for PATH resources * if stop command set to Halt immediately,driver will stop diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index fc6951b..020c3c8 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -104,8 +104,10 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, CAM_ISP_HW_CMD_CSID_QCFA_SUPPORTED, CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, + CAM_ISP_HW_CMD_QUERY_DSP_MODE, CAM_ISP_HW_CMD_DUMP_HW, CAM_ISP_HW_CMD_FE_TRIGGER_CMD, + CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index cd32edb..cb5d22c 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -594,6 +594,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CORE_CONFIG: case CAM_ISP_HW_CMD_BW_UPDATE_V2: case CAM_ISP_HW_CMD_DUMP_HW: + case CAM_ISP_HW_CMD_QUERY_DSP_MODE: rc = core_info->vfe_top->hw_ops.process_cmd( core_info->vfe_top->top_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c index 77e2a05..0d204b7 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #include <linux/slab.h> @@ -85,6 +85,9 @@ static int cam_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info) break; } + vfe_soc_private->dsp_disabled = of_property_read_bool(of_node, + "dsp-disabled"); + end: return rc; } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h index 082c535..3081274 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.h @@ -24,6 +24,7 @@ * @cpas_version: Has cpas version read from Hardware * @ubwc_static_ctrl: UBWC static control configuration * @is_ife_lite: Flag to indicate full vs lite IFE + * @dsp_disabled: Flag to indicate DSP is not supported for VFE */ struct cam_vfe_soc_private { uint32_t cpas_handle; @@ -33,6 +34,7 @@ struct cam_vfe_soc_private { int32_t dsp_clk_rate; uint32_t ubwc_static_ctrl[UBWC_STATIC_CONFIG_MAX]; bool is_ife_lite; + bool dsp_disabled; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c index 332332c..47d34b6 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c @@ -599,6 +599,31 @@ int cam_vfe_top_write(void *device_priv, return -EPERM; } +int cam_vfe_top_query_dsp_mode(struct cam_vfe_top_ver2_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + int rc = 0; + struct cam_hw_soc_info *soc_info = NULL; + struct cam_vfe_soc_private *soc_private = NULL; + + if (!top_priv) { + CAM_ERR(CAM_ISP, "Error! Invalid arguments"); + return -EINVAL; + } + + soc_info = top_priv->common_data.soc_info; + soc_private = soc_info->soc_private; + + if (!soc_private) { + CAM_ERR(CAM_ISP, "Error soc_private NULL"); + return -EINVAL; + } + + if (soc_private->dsp_disabled) + rc = -EINVAL; + return rc; +} + int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -651,6 +676,9 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type, rc = cam_vfe_hw_dump(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_QUERY_DSP_MODE: + rc = cam_vfe_top_query_dsp_mode(top_priv, cmd_args, arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c index dc15cab..a6f662f 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c @@ -508,6 +508,31 @@ int cam_vfe_top_ver3_write(void *device_priv, return -EPERM; } +int cam_vfe_top_ver3_query_dsp_mode(struct cam_vfe_top_ver3_priv *top_priv, + void *cmd_args, uint32_t arg_size) +{ + int rc = 0; + struct cam_hw_soc_info *soc_info = NULL; + struct cam_vfe_soc_private *soc_private = NULL; + + if (!top_priv) { + CAM_ERR(CAM_ISP, "Error, Invalid arguments"); + return -EINVAL; + } + + soc_info = top_priv->common_data.soc_info; + soc_private = soc_info->soc_private; + + if (!soc_private) { + CAM_ERR(CAM_ISP, "Error soc_private NULL"); + return -EINVAL; + } + + if (soc_private->dsp_disabled) + rc = -EINVAL; + return rc; +} + int cam_vfe_top_ver3_process_cmd(void *device_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -561,6 +586,10 @@ int cam_vfe_top_ver3_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_CORE_CONFIG: rc = cam_vfe_core_config_control(top_priv, cmd_args, arg_size); break; + case CAM_ISP_HW_CMD_QUERY_DSP_MODE: + rc = cam_vfe_top_ver3_query_dsp_mode(top_priv, cmd_args, + arg_size); + break; default: rc = -EINVAL; CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type); diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 3f2eaaa..4d6e4a4 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -1543,7 +1543,7 @@ static int cam_jpeg_mgr_hw_dump(void *hw_mgr_priv, void *dump_hw_args) hw_dump: cur_time = ktime_get(); - diff = ktime_us_delta(p_cfg_req->submit_timestamp, cur_time); + diff = ktime_us_delta(cur_time, p_cfg_req->submit_timestamp); cur_ts = ktime_to_timespec64(cur_time); req_ts = ktime_to_timespec64(p_cfg_req->submit_timestamp); diff --git a/drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c b/drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c index 5511913..64eee93 100644 --- a/drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c +++ b/drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_core.c @@ -115,7 +115,7 @@ static int cam_lrme_hw_dump( } cur_time = ktime_get(); - diff = ktime_us_delta(req->submit_timestamp, cur_time); + diff = ktime_us_delta(cur_time, req->submit_timestamp); cur_ts = ktime_to_timespec64(cur_time); req_ts = ktime_to_timespec64(req->submit_timestamp); diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index b410907..d02057a 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -347,7 +347,6 @@ int cam_flash_pmic_gpio_flush_request( if ((flash_data->opcode == CAMERA_SENSOR_FLASH_OP_OFF) && (flash_data->cmn_attr.request_id > 0) && - (flash_data->cmn_attr.request_id <= req_id) && flash_data->cmn_attr.is_settings_valid) { is_off_needed = true; CAM_DBG(CAM_FLASH, @@ -558,7 +557,7 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl) CAM_ERR(CAM_FLASH, "Flash control Null"); return -EINVAL; } - + CAM_DBG(CAM_FLASH, "Flash OFF Triggered"); if (flash_ctrl->switch_trigger) cam_res_mgr_led_trigger_event(flash_ctrl->switch_trigger, (enum led_brightness)LED_SWITCH_OFF); @@ -1613,6 +1612,8 @@ int cam_flash_pmic_gpio_pkt_parser( flash_data->led_current_ma[i] = flash_operation_info->led_current_ma[i]; + CAM_DBG(CAM_FLASH, + "FLASH_CMD_TYPE op:%d", flash_data->opcode); if (flash_data->opcode == CAMERA_SENSOR_FLASH_OP_OFF) add_req.skip_before_applying |= SKIP_NEXT_FRAME; } diff --git a/drivers/cam_utils/cam_cx_ipeak.c b/drivers/cam_utils/cam_cx_ipeak.c index b0f93ba..58246e8 100644 --- a/drivers/cam_utils/cam_cx_ipeak.c +++ b/drivers/cam_utils/cam_cx_ipeak.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include <linux/of.h> @@ -35,7 +35,7 @@ int cam_cx_ipeak_register_cx_ipeak(struct cam_hw_soc_info *soc_info) if (cam_cx_ipeak) { goto exit; } else { - rc = -EINVAL; + CAM_WARN(CAM_UTIL, "cx_ipeak_register failed"); goto exit; } diff --git a/drivers/cam_utils/cam_io_util.c b/drivers/cam_utils/cam_io_util.c index 6a17227..f3ad622 100644 --- a/drivers/cam_utils/cam_io_util.c +++ b/drivers/cam_utils/cam_io_util.c @@ -271,8 +271,8 @@ int cam_io_dump(void __iomem *base_addr, uint32_t start_offset, int size) p_str += 11; } data = readl_relaxed(base_addr + REG_OFFSET(start_offset, i)); - snprintf(p_str, 9, "%08x ", data); - p_str += 8; + snprintf(p_str, 10, "%08x ", data); + p_str += 9; if ((i + 1) % NUM_REGISTER_PER_LINE == 0) { CAM_ERR(CAM_UTIL, "%s", line_str); line_str[0] = '\0'; |