msm: camera: sync: Add SYNC_CANCEL support in sync driver

Add SYNC_CANCEL definition and signal CANCEL instead of
ERROR in flush cases.

CRs-Fixed: 2673810
Change-Id: I1bd83e382f9b38f5f020a5af3b883083e211e3d2
Signed-off-by: Pavan Kumar Chilamkurthi <pchilamk@codeaurora.org>
This commit is contained in:
Pavan Kumar Chilamkurthi
2020-04-27 20:59:07 -07:00
parent beb3ea37bb
commit 74410fea6b
6 changed files with 70 additions and 25 deletions

View File

@@ -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",

View File

@@ -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);
}

View File

@@ -2953,7 +2953,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,
@@ -4832,7 +4832,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);
}
@@ -4848,7 +4848,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);
}
@@ -4864,7 +4864,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);
}

View File

@@ -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(&params);
if (rc)

View File

@@ -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:

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved.
*/
#ifndef __UAPI_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