diff --git a/drivers/cam_core/cam_context_utils.c b/drivers/cam_core/cam_context_utils.c index 09f164561d..5b09d1183d 100644 --- a/drivers/cam_core/cam_context_utils.c +++ b/drivers/cam_core/cam_context_utils.c @@ -201,8 +201,10 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data) * in a critical section which is provided by this * mutex. */ - if (status == CAM_SYNC_STATE_SIGNALED_ERROR) { - CAM_DBG(CAM_CTXT, "fence error: %d", sync_obj); + if ((status == CAM_SYNC_STATE_SIGNALED_ERROR) || + (status == CAM_SYNC_STATE_SIGNALED_CANCEL)) { + CAM_DBG(CAM_CTXT, "fence error: %d on obj %d", + status, sync_obj); flush_cmd.req_id = req->request_id; cam_context_flush_req_to_hw(ctx, &flush_cmd); } @@ -660,7 +662,7 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) if (req->out_map_entries[i].sync_id != -1) { rc = cam_sync_signal( req->out_map_entries[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); if (rc == -EALREADY) { CAM_ERR(CAM_CTXT, "Req: %llu already signalled, sync_id:%d", @@ -732,7 +734,7 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) if (req->out_map_entries[i].sync_id != -1) { rc = cam_sync_signal( req->out_map_entries[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); if (rc == -EALREADY) { CAM_ERR(CAM_CTXT, "Req: %llu already signalled ctx: %pK dev_name: %s dev_handle: %d ctx_state: %d", @@ -845,7 +847,7 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, req->out_map_entries[i].sync_id; if (sync_id != -1) { rc = cam_sync_signal(sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); if (rc == -EALREADY) { CAM_ERR(CAM_CTXT, "Req: %llu already signalled, sync_id:%d", diff --git a/drivers/cam_cust/cam_custom_context.c b/drivers/cam_cust/cam_custom_context.c index 25e092841c..0fff3f0792 100644 --- a/drivers/cam_cust/cam_custom_context.c +++ b/drivers/cam_cust/cam_custom_context.c @@ -116,7 +116,7 @@ static int __cam_custom_ctx_flush_req(struct cam_context *ctx, req_custom->fence_map_out[i].sync_id); rc = cam_sync_signal( req_custom->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); if (rc) CAM_ERR_RATE_LIMIT(CAM_CUSTOM, "signal fence failed\n"); @@ -291,7 +291,7 @@ static int __cam_custom_stop_dev_core( if (req_custom->fence_map_out[i].sync_id != -1) { cam_sync_signal( req_custom->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); } list_add_tail(&req->list, &ctx->free_req_list); } @@ -307,7 +307,7 @@ static int __cam_custom_stop_dev_core( if (req_custom->fence_map_out[i].sync_id != -1) { cam_sync_signal( req_custom->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); } list_add_tail(&req->list, &ctx->free_req_list); } @@ -323,7 +323,7 @@ static int __cam_custom_stop_dev_core( if (req_custom->fence_map_out[i].sync_id != -1) { cam_sync_signal( req_custom->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); } list_add_tail(&req->list, &ctx->free_req_list); } diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 13cd4ae74d..2091399a6d 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -2955,7 +2955,7 @@ static int __cam_isp_ctx_flush_req(struct cam_context *ctx, req_isp->fence_map_out[i].sync_id); rc = cam_sync_signal( req_isp->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); if (rc) { tmp = req_isp->fence_map_out[i].sync_id; CAM_ERR_RATE_LIMIT(CAM_ISP, @@ -4834,7 +4834,7 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( if (req_isp->fence_map_out[i].sync_id != -1) { cam_sync_signal( req_isp->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); } list_add_tail(&req->list, &ctx->free_req_list); } @@ -4850,7 +4850,7 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( if (req_isp->fence_map_out[i].sync_id != -1) { cam_sync_signal( req_isp->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); } list_add_tail(&req->list, &ctx->free_req_list); } @@ -4866,7 +4866,7 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( if (req_isp->fence_map_out[i].sync_id != -1) { cam_sync_signal( req_isp->fence_map_out[i].sync_id, - CAM_SYNC_STATE_SIGNALED_ERROR); + CAM_SYNC_STATE_SIGNALED_CANCEL); } list_add_tail(&req->list, &ctx->free_req_list); } diff --git a/drivers/cam_sync/cam_sync.c b/drivers/cam_sync/cam_sync.c index 8f38bcca16..a984a7be8f 100644 --- a/drivers/cam_sync/cam_sync.c +++ b/drivers/cam_sync/cam_sync.c @@ -110,8 +110,9 @@ int cam_sync_register_callback(sync_callback cb_func, } /* Trigger callback if sync object is already in SIGNALED state */ - if ((row->state == CAM_SYNC_STATE_SIGNALED_SUCCESS || - row->state == CAM_SYNC_STATE_SIGNALED_ERROR) && + if (((row->state == CAM_SYNC_STATE_SIGNALED_SUCCESS) || + (row->state == CAM_SYNC_STATE_SIGNALED_ERROR) || + (row->state == CAM_SYNC_STATE_SIGNALED_CANCEL)) && (!row->remaining)) { if (trigger_cb_without_switch) { CAM_DBG(CAM_SYNC, "Invoke callback for sync object:%d", @@ -222,8 +223,9 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status) return -EALREADY; } - if (status != CAM_SYNC_STATE_SIGNALED_SUCCESS && - status != CAM_SYNC_STATE_SIGNALED_ERROR) { + if ((status != CAM_SYNC_STATE_SIGNALED_SUCCESS) && + (status != CAM_SYNC_STATE_SIGNALED_ERROR) && + (status != CAM_SYNC_STATE_SIGNALED_CANCEL)) { spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]); CAM_ERR(CAM_SYNC, "Error: signaling with undefined status = %d", @@ -439,6 +441,7 @@ int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms) case CAM_SYNC_STATE_INVALID: case CAM_SYNC_STATE_ACTIVE: case CAM_SYNC_STATE_SIGNALED_ERROR: + case CAM_SYNC_STATE_SIGNALED_CANCEL: CAM_ERR(CAM_SYNC, "Error: Wait on invalid state = %d, obj = %d", row->state, sync_obj); @@ -653,8 +656,9 @@ static int cam_sync_handle_register_user_payload( return -EINVAL; } - if (row->state == CAM_SYNC_STATE_SIGNALED_SUCCESS || - row->state == CAM_SYNC_STATE_SIGNALED_ERROR) { + if ((row->state == CAM_SYNC_STATE_SIGNALED_SUCCESS) || + (row->state == CAM_SYNC_STATE_SIGNALED_ERROR) || + (row->state == CAM_SYNC_STATE_SIGNALED_CANCEL)) { cam_sync_util_send_v4l2_event(CAM_SYNC_V4L_EVENT_ID_CB_TRIG, sync_obj, @@ -1033,6 +1037,41 @@ static int cam_sync_create_debugfs(void) } #if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX) +int cam_synx_sync_signal(int32_t sync_obj, uint32_t synx_status) +{ + int rc = 0; + uint32_t sync_status = synx_status; + + switch (synx_status) { + case SYNX_STATE_ACTIVE: + sync_status = CAM_SYNC_STATE_ACTIVE; + break; + case SYNX_STATE_SIGNALED_SUCCESS: + sync_status = CAM_SYNC_STATE_SIGNALED_SUCCESS; + break; + case SYNX_STATE_SIGNALED_ERROR: + sync_status = CAM_SYNC_STATE_SIGNALED_ERROR; + break; + case 4: /* SYNX_STATE_SIGNALED_CANCEL: */ + sync_status = CAM_SYNC_STATE_SIGNALED_CANCEL; + break; + default: + CAM_ERR(CAM_SYNC, "Invalid synx status %d for obj %d", + synx_status, sync_obj); + sync_status = CAM_SYNC_STATE_SIGNALED_ERROR; + break; + } + + rc = cam_sync_signal(sync_obj, sync_status); + if (rc) { + CAM_ERR(CAM_SYNC, + "synx signal failed with %d, sync_obj=%d, synx_status=%d, sync_status=%d", + sync_obj, synx_status, sync_status, rc); + } + + return rc; +} + static int cam_sync_register_synx_bind_ops(void) { int rc = 0; @@ -1043,7 +1082,7 @@ static int cam_sync_register_synx_bind_ops(void) params.ops.register_callback = cam_sync_register_callback; params.ops.deregister_callback = cam_sync_deregister_callback; params.ops.enable_signaling = cam_sync_get_obj_ref; - params.ops.signal = cam_sync_signal; + params.ops.signal = cam_synx_sync_signal; rc = synx_register_ops(¶ms); if (rc) diff --git a/drivers/cam_sync/cam_sync_util.c b/drivers/cam_sync/cam_sync_util.c index d7e0f41252..44a7bd4d05 100644 --- a/drivers/cam_sync/cam_sync_util.c +++ b/drivers/cam_sync/cam_sync_util.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved. */ #include "cam_sync_util.h" @@ -88,8 +88,9 @@ int cam_sync_init_group_object(struct sync_table_row *table, } /* check for child's state */ - if (child_row->state == CAM_SYNC_STATE_SIGNALED_ERROR) { - row->state = CAM_SYNC_STATE_SIGNALED_ERROR; + if ((child_row->state == CAM_SYNC_STATE_SIGNALED_ERROR) || + (child_row->state == CAM_SYNC_STATE_SIGNALED_CANCEL)) { + row->state = child_row->state; spin_unlock_bh(&sync_dev->row_spinlocks[sync_objs[i]]); continue; } @@ -123,7 +124,8 @@ int cam_sync_init_group_object(struct sync_table_row *table, } if (!row->remaining) { - if (row->state != CAM_SYNC_STATE_SIGNALED_ERROR) + if ((row->state != CAM_SYNC_STATE_SIGNALED_ERROR) && + (row->state != CAM_SYNC_STATE_SIGNALED_CANCEL)) row->state = CAM_SYNC_STATE_SIGNALED_SUCCESS; complete_all(&row->signaled); } @@ -392,6 +394,7 @@ int cam_sync_util_update_parent_state(struct sync_table_row *parent_row, break; case CAM_SYNC_STATE_SIGNALED_ERROR: + case CAM_SYNC_STATE_SIGNALED_CANCEL: break; case CAM_SYNC_STATE_INVALID: diff --git a/include/uapi/camera/media/cam_sync.h b/include/uapi/camera/media/cam_sync.h index 0c97982c98..c2031c5d8e 100644 --- a/include/uapi/camera/media/cam_sync.h +++ b/include/uapi/camera/media/cam_sync.h @@ -35,6 +35,7 @@ #define CAM_SYNC_STATE_ACTIVE 1 #define CAM_SYNC_STATE_SIGNALED_SUCCESS 2 #define CAM_SYNC_STATE_SIGNALED_ERROR 3 +#define CAM_SYNC_STATE_SIGNALED_CANCEL 4 /** * struct cam_sync_ev_header - Event header for sync event notification