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

Esse commit está contido em:
qctecmdr
2022-04-16 11:02:44 -07:00
commit de Gerrit - the friendly Code Review server
4 arquivos alterados com 49 adições e 2 exclusões

Ver arquivo

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

Ver arquivo

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

Ver arquivo

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

Ver arquivo

@@ -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;
@@ -276,6 +305,13 @@ static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
ret = -EINVAL;
goto end;
}
if (fence_array->fences) {
pr_err("fence array already populated, spec fd:%d status:%d flags:0x%x\n",
sync_bind_info->out_bind_fd, dma_fence_get_status(fence), fence->flags);
goto end;
}
num_fences = fence_array->num_fences;
counter = num_fences;
@@ -298,11 +334,12 @@ static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
goto out;
}
spin_lock(fence->lock);
fence_array->fences = fence_list;
for (i = 0; i < num_fences; i++) {
user_fence = sync_file_get_fence(user_fds[i]);
if (!user_fence) {
pr_err("bind fences are invalid !! user_fd:%d out_bind_fd:%d\n",
pr_warn("bind fences are invalid !! user_fd:%d out_bind_fd:%d\n",
user_fds[i], sync_bind_info->out_bind_fd);
counter = i;
ret = -EINVAL;
@@ -314,11 +351,15 @@ static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
}
clear_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags);
spin_unlock(fence->lock);
dma_fence_enable_sw_signaling(&fence_array->base);
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]);
@@ -327,6 +368,7 @@ bind_invalid:
fence_array->fences = NULL;
fence_array->num_fences = 0;
dma_fence_set_error(fence, -EINVAL);
spin_unlock(fence->lock);
dma_fence_signal(fence);
clear_fence_array_tracker(false);
}
@@ -424,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;