Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21227d55 authored by Terence Ho's avatar Terence Ho
Browse files

msm:ais: add sync multiclient create and reset extension



Add sync extension to create object with client id param that will
be offset of v4l2 event used. Also add reset API to enable reuse
of signalled sync objects.

Change-Id: I0d2297a57367b1cc81e48848de640df860078e70
Signed-off-by: default avatarTerence Ho <terenceh@codeaurora.org>
parent b62aaff3
Loading
Loading
Loading
Loading
+102 −3
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ void cam_sync_print_fence_table(void)
	}
}

int cam_sync_create(int32_t *sync_obj, const char *name)
int cam_sync_create(int32_t *sync_obj, const char *name, uint32_t client_id)
{
	int rc;
	long idx;
@@ -66,7 +66,7 @@ int cam_sync_create(int32_t *sync_obj, const char *name)

	spin_lock_bh(&sync_dev->row_spinlocks[idx]);
	rc = cam_sync_init_row(sync_dev->sync_table, idx, name,
		CAM_SYNC_TYPE_INDV);
		CAM_SYNC_TYPE_INDV, client_id);
	if (rc) {
		CAM_ERR(CAM_SYNC, "Error: Unable to init row at idx = %ld",
			idx);
@@ -408,6 +408,7 @@ int cam_sync_check_valid(int32_t sync_obj)
	}
	return 0;
}

int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms)
{
	unsigned long timeleft;
@@ -455,6 +456,43 @@ int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms)
	return rc;
}

static int cam_sync_reset(int32_t sync_obj)
{
	int rc = 0;
	struct sync_table_row *row = NULL;

	if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
		return -EINVAL;

	row = sync_dev->sync_table + sync_obj;

	spin_lock_bh(&sync_dev->row_spinlocks[sync_obj]);

	if (row->state == CAM_SYNC_STATE_INVALID) {
		CAM_ERR(CAM_SYNC,
			"Error: accessing an uninitialized sync obj = %d",
			sync_obj);
		spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
		return -EINVAL;
	}

	row->state = CAM_SYNC_STATE_ACTIVE;

	row->remaining = 0;
	atomic_set(&row->ref_cnt, 0);

	reinit_completion(&row->signaled);

	INIT_LIST_HEAD(&row->callback_list);
	INIT_LIST_HEAD(&row->parents_list);
	INIT_LIST_HEAD(&row->children_list);
	INIT_LIST_HEAD(&row->user_payload_list);

	spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);

	return rc;
}

static int cam_sync_handle_create(struct cam_private_ioctl_arg *k_ioctl)
{
	struct cam_sync_info sync_create;
@@ -473,7 +511,37 @@ static int cam_sync_handle_create(struct cam_private_ioctl_arg *k_ioctl)

	mutex_lock(&sync_dev->table_lock);
	result = cam_sync_create(&sync_create.sync_obj,
		sync_create.name);
		sync_create.name, 0);
	mutex_unlock(&sync_dev->table_lock);
	if (!result)
		if (copy_to_user(
			u64_to_user_ptr(k_ioctl->ioctl_ptr),
			&sync_create,
			k_ioctl->size))
			return -EFAULT;

	return result;
}

static int cam_sync_handle_create2(struct cam_private_ioctl_arg *k_ioctl)
{
	struct cam_sync_create2 sync_create;
	int result;

	if (k_ioctl->size != sizeof(struct cam_sync_create2))
		return -EINVAL;

	if (!k_ioctl->ioctl_ptr)
		return -EINVAL;

	if (copy_from_user(&sync_create,
		u64_to_user_ptr(k_ioctl->ioctl_ptr),
		k_ioctl->size))
		return -EFAULT;

	mutex_lock(&sync_dev->table_lock);
	result = cam_sync_create(&sync_create.sync_obj,
		sync_create.name, sync_create.client_id);
	mutex_unlock(&sync_dev->table_lock);
	if (!result)
		if (copy_to_user(
@@ -663,6 +731,7 @@ static int cam_sync_handle_register_user_payload(

		cam_sync_util_send_v4l2_event(CAM_SYNC_V4L_EVENT_ID_CB_TRIG,
			sync_obj,
			row->client_id,
			row->state,
			user_payload_kernel->payload_data,
			CAM_SYNC_USER_PAYLOAD_SIZE * sizeof(__u64));
@@ -745,6 +814,30 @@ static int cam_sync_handle_deregister_user_payload(
	return 0;
}

static int cam_sync_handle_reset(struct cam_private_ioctl_arg *k_ioctl)
{
	struct cam_sync_userpayload_info sync_reset;
	int rc;

	if (k_ioctl->size != sizeof(struct cam_sync_userpayload_info))
		return -EINVAL;

	if (!k_ioctl->ioctl_ptr)
		return -EINVAL;

	if (copy_from_user(&sync_reset,
		u64_to_user_ptr(k_ioctl->ioctl_ptr),
		k_ioctl->size))
		return -EFAULT;

	rc = cam_sync_reset(sync_reset.sync_obj);

	if (!rc)
		rc = cam_sync_handle_register_user_payload(k_ioctl);

	return rc;
}

static long cam_sync_dev_ioctl(struct file *filep, void *fh,
		bool valid_prio, unsigned int cmd, void *arg)
{
@@ -791,6 +884,12 @@ static long cam_sync_dev_ioctl(struct file *filep, void *fh,
		((struct cam_private_ioctl_arg *)arg)->result =
			k_ioctl.result;
		break;
	case CAM_SYNC_CREATE2:
		rc = cam_sync_handle_create2(&k_ioctl);
		break;
	case CAM_SYNC_RESET:
		rc = cam_sync_handle_reset(&k_ioctl);
		break;
	default:
		rc = -ENOIOCTLCMD;
	}
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ typedef void (*sync_callback)(int32_t sync_obj, int status, void *data);
 * -ENOMEM will be returned if the kernel can't allocate space for
 * sync object.
 */
int cam_sync_create(int32_t *sync_obj, const char *name);
int cam_sync_create(int32_t *sync_obj, const char *name, uint32_t client_id);

/**
 * @brief: Registers a callback with a sync object
+1 −0
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ struct sync_table_row {
	struct list_head callback_list;
	struct list_head user_payload_list;
	atomic_t ref_cnt;
	uint32_t client_id;
};

/**
+8 −4
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -32,7 +32,7 @@ int cam_sync_util_find_and_set_empty_row(struct sync_device *sync_dev,
}

int cam_sync_init_row(struct sync_table_row *table,
	uint32_t idx, const char *name, uint32_t type)
	uint32_t idx, const char *name, uint32_t type, uint32_t client_id)
{
	struct sync_table_row *row = table + idx;

@@ -46,6 +46,7 @@ int cam_sync_init_row(struct sync_table_row *table,
	INIT_LIST_HEAD(&row->parents_list);
	INIT_LIST_HEAD(&row->children_list);
	row->type = type;
	row->client_id = client_id;
	row->sync_id = idx;
	row->state = CAM_SYNC_STATE_ACTIVE;
	row->remaining = 0;
@@ -71,7 +72,7 @@ int cam_sync_init_group_object(struct sync_table_row *table,
	struct sync_table_row *row = table + idx;
	struct sync_table_row *child_row = NULL;

	cam_sync_init_row(table, idx, "merged_fence", CAM_SYNC_TYPE_GROUP);
	cam_sync_init_row(table, idx, "merged_fence", CAM_SYNC_TYPE_GROUP, 0);

	/*
	 * While traversing for children, parent's row list is updated with
@@ -105,6 +106,7 @@ int cam_sync_init_group_object(struct sync_table_row *table,
			continue;
		}

		row->client_id = child_row->client_id;
		row->remaining++;

		/* Add child info */
@@ -342,6 +344,7 @@ void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj,
		cam_sync_util_send_v4l2_event(
			CAM_SYNC_V4L_EVENT_ID_CB_TRIG,
			sync_obj,
			signalable_row->client_id,
			status,
			payload_info->payload_data,
			CAM_SYNC_PAYLOAD_WORDS * sizeof(__u64));
@@ -364,6 +367,7 @@ void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj,

void cam_sync_util_send_v4l2_event(uint32_t id,
	uint32_t sync_obj,
	uint32_t client_id,
	int status,
	void *payload,
	int len)
@@ -373,7 +377,7 @@ void cam_sync_util_send_v4l2_event(uint32_t id,
	struct cam_sync_ev_header *ev_header = NULL;

	event.id = id;
	event.type = CAM_SYNC_V4L_EVENT;
	event.type = CAM_SYNC_V4L_EVENT + client_id;

	ev_header = CAM_SYNC_GET_HEADER_PTR(event);
	ev_header->sync_obj = sync_obj;
+3 −4
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -45,7 +45,7 @@ int cam_sync_util_find_and_set_empty_row(struct sync_device *sync_dev,
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_sync_init_row(struct sync_table_row *table,
	uint32_t idx, const char *name, uint32_t type);
	uint32_t idx, const char *name, uint32_t type, uint32_t client_id);

/**
 * @brief: Function to uninitialize a row in the sync table
@@ -74,8 +74,6 @@ int cam_sync_init_group_object(struct sync_table_row *table,
	uint32_t *sync_objs,
	uint32_t num_objs);

int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx);

/**
 * @brief: Function to dispatch a kernel callback for a sync callback
 *
@@ -109,6 +107,7 @@ void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj,
 */
void cam_sync_util_send_v4l2_event(uint32_t id,
	uint32_t sync_obj,
	uint32_t client_id,
	int status,
	void *payload,
	int len);
Loading