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

Commit 0058766c authored by Jeyaprakash Soundrapandian's avatar Jeyaprakash Soundrapandian Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: sync: Validate if fence is already signaled" into dev/msm-4.14-camx

parents 2e180d28 a5d80639
Loading
Loading
Loading
Loading
+53 −11
Original line number Diff line number Diff line
@@ -21,6 +21,13 @@

struct sync_device *sync_dev;

/*
 * Flag to determine whether to enqueue cb of a
 * signaled fence onto the workq or invoke it
 * directly in the same context
 */
static bool trigger_cb_without_switch;

int cam_sync_create(int32_t *sync_obj, const char *name)
{
	int rc;
@@ -58,6 +65,7 @@ int cam_sync_register_callback(sync_callback cb_func,
	struct sync_callback_info *sync_cb;
	struct sync_callback_info *cb_info;
	struct sync_table_row *row = NULL;
	int status = 0;

	if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0 || !cb_func)
		return -EINVAL;
@@ -94,18 +102,27 @@ int cam_sync_register_callback(sync_callback cb_func,
	if ((row->state == CAM_SYNC_STATE_SIGNALED_SUCCESS ||
		row->state == CAM_SYNC_STATE_SIGNALED_ERROR) &&
		(!row->remaining)) {
		if (trigger_cb_without_switch) {
			CAM_DBG(CAM_SYNC, "Invoke callback for sync object:%d",
				sync_obj);
			status = row->state;
			kfree(sync_cb);
			spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
			cb_func(sync_obj, status, userdata);
		} else {
			sync_cb->callback_func = cb_func;
			sync_cb->cb_data = userdata;
			sync_cb->sync_obj = sync_obj;
			INIT_WORK(&sync_cb->cb_dispatch_work,
				cam_sync_util_cb_dispatch);
			sync_cb->status = row->state;
		CAM_DBG(CAM_SYNC, "Callback trigger for sync object:%d",
			CAM_DBG(CAM_SYNC, "Enqueue callback for sync object:%d",
				sync_cb->sync_obj);
			queue_work(sync_dev->work_queue,
				&sync_cb->cb_dispatch_work);

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

		return 0;
	}

@@ -952,6 +969,26 @@ static void cam_sync_init_entity(struct sync_device *sync_dev)
}
#endif

static int cam_sync_create_debugfs(void)
{
	sync_dev->dentry = debugfs_create_dir("camera_sync", NULL);

	if (!sync_dev->dentry) {
		CAM_ERR(CAM_SYNC, "Failed to create sync dir");
		return -ENOMEM;
	}

	if (!debugfs_create_bool("trigger_cb_without_switch",
		0644, sync_dev->dentry,
		&trigger_cb_without_switch)) {
		CAM_ERR(CAM_SYNC,
			"failed to create trigger_cb_without_switch entry");
		return -ENOMEM;
	}

	return 0;
}

static int cam_sync_probe(struct platform_device *pdev)
{
	int rc;
@@ -1017,6 +1054,9 @@ static int cam_sync_probe(struct platform_device *pdev)
		goto v4l2_fail;
	}

	trigger_cb_without_switch = false;
	cam_sync_create_debugfs();

	return rc;

v4l2_fail:
@@ -1036,6 +1076,8 @@ static int cam_sync_remove(struct platform_device *pdev)
	v4l2_device_unregister(sync_dev->vdev->v4l2_dev);
	cam_sync_media_controller_cleanup(sync_dev);
	video_device_release(sync_dev->vdev);
	debugfs_remove_recursive(sync_dev->dentry);
	sync_dev->dentry = NULL;
	kfree(sync_dev);
	sync_dev = NULL;

+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/debugfs.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
@@ -177,6 +178,7 @@ struct cam_signalable_info {
 * @row_spinlocks   : Spinlock array, one for each row in the table
 * @table_lock      : Mutex used to lock the table
 * @open_cnt        : Count of file open calls made on the sync driver
 * @dentry          : Debugfs entry
 * @work_queue      : Work queue used for dispatching kernel callbacks
 * @cam_sync_eventq : Event queue used to dispatch user payloads to user space
 * @bitmap          : Bitmap representation of all sync objects
@@ -188,6 +190,7 @@ struct sync_device {
	spinlock_t row_spinlocks[CAM_SYNC_MAX_OBJS];
	struct mutex table_lock;
	int open_cnt;
	struct dentry *dentry;
	struct workqueue_struct *work_queue;
	struct v4l2_fh *cam_sync_eventq;
	spinlock_t cam_sync_eventq_lock;