mirror of https://github.com/OpenIPC/firmware.git
144 lines
4.2 KiB
Diff
144 lines
4.2 KiB
Diff
--- linux-4.9.37/drivers/dma-buf/sync_file.c 2017-07-12 16:42:41.000000000 +0300
|
|
+++ linux-4.9.y/drivers/dma-buf/sync_file.c 2021-06-07 13:01:33.000000000 +0300
|
|
@@ -67,9 +67,10 @@
|
|
* sync_file_create() - creates a sync file
|
|
* @fence: fence to add to the sync_fence
|
|
*
|
|
- * Creates a sync_file containg @fence. Once this is called, the sync_file
|
|
- * takes ownership of @fence. The sync_file can be released with
|
|
- * fput(sync_file->file). Returns the sync_file or NULL in case of error.
|
|
+ * Creates a sync_file containg @fence. This function acquires and additional
|
|
+ * reference of @fence for the newly-created &sync_file, if it succeeds. The
|
|
+ * sync_file can be released with fput(sync_file->file). Returns the
|
|
+ * sync_file or NULL in case of error.
|
|
*/
|
|
struct sync_file *sync_file_create(struct fence *fence)
|
|
{
|
|
@@ -79,7 +80,7 @@
|
|
if (!sync_file)
|
|
return NULL;
|
|
|
|
- sync_file->fence = fence;
|
|
+ sync_file->fence = fence_get(fence);
|
|
|
|
snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d",
|
|
fence->ops->get_driver_name(fence),
|
|
@@ -90,14 +91,7 @@
|
|
}
|
|
EXPORT_SYMBOL(sync_file_create);
|
|
|
|
-/**
|
|
- * sync_file_fdget() - get a sync_file from an fd
|
|
- * @fd: fd referencing a fence
|
|
- *
|
|
- * Ensures @fd references a valid sync_file, increments the refcount of the
|
|
- * backing file. Returns the sync_file or NULL in case of error.
|
|
- */
|
|
-static struct sync_file *sync_file_fdget(int fd)
|
|
+struct sync_file *sync_file_fdget(int fd)
|
|
{
|
|
struct file *file = fget(fd);
|
|
|
|
@@ -114,6 +108,8 @@
|
|
return NULL;
|
|
}
|
|
|
|
+EXPORT_SYMBOL(sync_file_fdget);
|
|
+
|
|
/**
|
|
* sync_file_get_fence - get the fence related to the sync_file fd
|
|
* @fd: sync_file fd to get the fence from
|
|
@@ -305,10 +301,9 @@
|
|
|
|
poll_wait(file, &sync_file->wq, wait);
|
|
|
|
- if (!poll_does_not_wait(wait) &&
|
|
- !test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) {
|
|
+ if (!test_and_set_bit(POLL_ENABLED, &sync_file->fence->flags)) {
|
|
if (fence_add_callback(sync_file->fence, &sync_file->cb,
|
|
- fence_check_cb_func) < 0)
|
|
+ fence_check_cb_func) < 0)
|
|
wake_up_all(&sync_file->wq);
|
|
}
|
|
|
|
@@ -370,7 +365,7 @@
|
|
return err;
|
|
}
|
|
|
|
-static void sync_fill_fence_info(struct fence *fence,
|
|
+static int sync_fill_fence_info(struct fence *fence,
|
|
struct sync_fence_info *info)
|
|
{
|
|
strlcpy(info->obj_name, fence->ops->get_timeline_name(fence),
|
|
@@ -382,6 +377,8 @@
|
|
else
|
|
info->status = 0;
|
|
info->timestamp_ns = ktime_to_ns(fence->timestamp);
|
|
+
|
|
+ return info->status;
|
|
}
|
|
|
|
static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
|
|
@@ -407,8 +404,12 @@
|
|
* sync_fence_info and return the actual number of fences on
|
|
* info->num_fences.
|
|
*/
|
|
- if (!info.num_fences)
|
|
+ if (!info.num_fences) {
|
|
+ info.status = fence_is_signaled(sync_file->fence);
|
|
goto no_fences;
|
|
+ } else {
|
|
+ info.status = 1;
|
|
+ }
|
|
|
|
if (info.num_fences < num_fences)
|
|
return -EINVAL;
|
|
@@ -418,8 +419,10 @@
|
|
if (!fence_info)
|
|
return -ENOMEM;
|
|
|
|
- for (i = 0; i < num_fences; i++)
|
|
- sync_fill_fence_info(fences[i], &fence_info[i]);
|
|
+ for (i = 0; i < num_fences; i++) {
|
|
+ int status = sync_fill_fence_info(fences[i], &fence_info[i]);
|
|
+ info.status = info.status <= 0 ? info.status : status;
|
|
+ }
|
|
|
|
if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info,
|
|
size)) {
|
|
@@ -429,7 +432,6 @@
|
|
|
|
no_fences:
|
|
strlcpy(info.name, sync_file->name, sizeof(info.name));
|
|
- info.status = fence_is_signaled(sync_file->fence);
|
|
info.num_fences = num_fences;
|
|
|
|
if (copy_to_user((void __user *)arg, &info, sizeof(info)))
|
|
@@ -443,12 +445,26 @@
|
|
return ret;
|
|
}
|
|
|
|
+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32)
|
|
+static long sync_fence_ioctl_wait(struct sync_file *sync_file, unsigned long arg)
|
|
+{
|
|
+ __s32 value;
|
|
+
|
|
+ if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
|
|
+ return -EFAULT;
|
|
+ if(value <= 0)
|
|
+ value = MAX_SCHEDULE_TIMEOUT;
|
|
+ return fence_wait_timeout(sync_file->fence, true, value);
|
|
+}
|
|
+
|
|
static long sync_file_ioctl(struct file *file, unsigned int cmd,
|
|
unsigned long arg)
|
|
{
|
|
struct sync_file *sync_file = file->private_data;
|
|
|
|
switch (cmd) {
|
|
+ case SYNC_IOC_WAIT:
|
|
+ return sync_fence_ioctl_wait(sync_file, arg);
|
|
case SYNC_IOC_MERGE:
|
|
return sync_file_ioctl_merge(sync_file, arg);
|
|
|