@@ -31,6 +31,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/reservation.h>
+#include <linux/dmabuf-sync.h>
static inline int is_dma_buf_file(struct file *);
@@ -82,9 +83,42 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
return dmabuf->ops->mmap(dmabuf, vma);
}
+static int dma_buf_lock(struct file *file, int cmd, struct file_lock *fl)
+{
+ struct dma_buf *dmabuf;
+ unsigned int type;
+ bool wait = false;
+
+ if (!is_dma_buf_file(file))
+ return -EINVAL;
+
+ dmabuf = file->private_data;
+
+ if ((fl->fl_type & F_UNLCK) == F_UNLCK) {
+ dmabuf_sync_single_unlock(dmabuf);
+ return 0;
+ }
+
+ /* convert flock type to dmabuf sync type. */
+ if ((fl->fl_type & F_WRLCK) == F_WRLCK)
+ type = DMA_BUF_ACCESS_W;
+ else if ((fl->fl_type & F_RDLCK) == F_RDLCK)
+ type = DMA_BUF_ACCESS_R;
+ else
+ return -EINVAL;
+
+ if (fl->fl_flags & FL_SLEEP)
+ wait = true;
+
+ /* TODO. the locking to certain region should also be considered. */
+
+ return dmabuf_sync_single_lock(dmabuf, type, wait);
+}
+
static const struct file_operations dma_buf_fops = {
.release = dma_buf_release,
.mmap = dma_buf_mmap_internal,
+ .lock = dma_buf_lock,
};
/*