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

Commit 8eb02819 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm:ais: add sync multiclient create and reset extension"

parents aa05a104 21227d55
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