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);
 | |
|  
 |