浏览代码

mm-drivers: sync: add api to wait for sync fence bind

This change adds an api to check if a given speculative
fence is bound. If fence is not bound, it will wait for the
speculative fence ioctl to bind the fence, or else timeout.

Change-Id: I9a86d09df410e89137264be47763ae39f06eea2b
Signed-off-by: Ingrid Gallardo <[email protected]>
Ingrid Gallardo 3 年之前
父节点
当前提交
7deaa67238
共有 4 个文件被更改,包括 38 次插入1 次删除
  1. 1 0
      config/kalamammdrivers.conf
  2. 1 0
      config/kalamammdriversconf.h
  3. 2 0
      sync_fence/Kbuild
  4. 34 1
      sync_fence/src/qcom_sync_file.c

+ 1 - 0
config/kalamammdrivers.conf

@@ -3,3 +3,4 @@
 # Copyright (c) 2020, The Linux Foundation. All rights reserved.
 
 export CONFIG_MSM_EXT_DISPLAY=y
+export CONFIG_QCOM_SPEC_SYNC=y

+ 1 - 0
config/kalamammdriversconf.h

@@ -5,3 +5,4 @@
  */
 
 #define CONFIG_MSM_EXT_DISPLAY 1
+#define CONFIG_QCOM_SPEC_SYNC 1

+ 2 - 0
sync_fence/Kbuild

@@ -3,8 +3,10 @@
 KDIR := $(TOP)/kernel_platform/msm-kernel
 LINUXINCLUDE    += -I$(SYNC_FENCE_ROOT)sync_fence/include/
 
+ifdef CONFIG_QCOM_SPEC_SYNC
 obj-m += sync_fence.o
 
 sync_fence-y := src/qcom_sync_file.o
 
 CDEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"
+endif

+ 34 - 1
sync_fence/src/qcom_sync_file.c

@@ -20,13 +20,13 @@
 #include <linux/dma-fence-array.h>
 #include <linux/sync_file.h>
 #include <uapi/sync_fence/qcom_sync_file.h>
+#include <linux/soc/qcom/qcom_sync_file.h>
 
 #define CLASS_NAME	"sync"
 #define DRV_NAME	"spec_sync"
 #define DRV_VERSION	1
 #define NAME_LEN	32
 
-#define SPEC_FENCE_FLAG_FENCE_ARRAY 0x10 /* user flags for debug */
 #define FENCE_MIN	1
 #define FENCE_MAX	32
 
@@ -44,6 +44,7 @@ struct sync_device {
 	uint32_t version;
 	struct mutex l_lock;
 	struct list_head fence_array_list;
+	wait_queue_head_t wait_queue;
 };
 
 struct fence_array_node {
@@ -254,6 +255,34 @@ static int spec_sync_ioctl_create_fence(struct sync_device *obj, unsigned long _
 	return 0;
 }
 
+int spec_sync_wait_bind_array(struct dma_fence_array *fence_array, u32 timeout_ms)
+{
+	int ret;
+
+	/* Check if fence-array is a speculative fence */
+	if (!fence_array || !test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY, &fence_array->base.flags)) {
+		pr_err("invalid fence!\n");
+		return -EINVAL;
+	} else if (test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY_BOUND, &fence_array->base.flags)) {
+		/* This fence-array is already bound, just return success */
+		return 0;
+	}
+
+	/* Wait for the fence-array bind */
+	ret = wait_event_timeout(sync_dev.wait_queue,
+		test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY_BOUND, &fence_array->base.flags),
+		msecs_to_jiffies(timeout_ms));
+	if (!ret) {
+		pr_err("timed out waiting for bind fence-array %d\n", timeout_ms);
+		ret = -ETIMEDOUT;
+	} else {
+		ret = 0;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(spec_sync_wait_bind_array);
+
 static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
 {
 	struct dma_fence_array *fence_array;
@@ -328,6 +357,9 @@ static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
 	clear_fence_array_tracker(false);
 
 bind_invalid:
+	set_bit(SPEC_FENCE_FLAG_FENCE_ARRAY_BOUND, &fence_array->base.flags);
+	wake_up_all(&sync_dev.wait_queue);
+
 	if (ret) {
 		for (i = counter - 1; i >= 0; i--)
 			dma_fence_put(fence_array->fences[i]);
@@ -434,6 +466,7 @@ static int spec_sync_register_device(void)
 	mutex_init(&sync_dev.lock);
 	mutex_init(&sync_dev.l_lock);
 	INIT_LIST_HEAD(&sync_dev.fence_array_list);
+	init_waitqueue_head(&sync_dev.wait_queue);
 
 	return 0;