Merge tag 'media/v4.20-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[muen/linux.git] / drivers / media / media-device.c
index 4c7190d..bed2437 100644 (file)
@@ -30,6 +30,7 @@
 #include <media/media-device.h>
 #include <media/media-devnode.h>
 #include <media/media-entity.h>
+#include <media/media-request.h>
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 
@@ -377,10 +378,19 @@ static long media_device_get_topology(struct media_device *mdev, void *arg)
        return ret;
 }
 
+static long media_device_request_alloc(struct media_device *mdev,
+                                      int *alloc_fd)
+{
+       if (!mdev->ops || !mdev->ops->req_validate || !mdev->ops->req_queue)
+               return -ENOTTY;
+
+       return media_request_alloc(mdev, alloc_fd);
+}
+
 static long copy_arg_from_user(void *karg, void __user *uarg, unsigned int cmd)
 {
-       /* All media IOCTLs are _IOWR() */
-       if (copy_from_user(karg, uarg, _IOC_SIZE(cmd)))
+       if ((_IOC_DIR(cmd) & _IOC_WRITE) &&
+           copy_from_user(karg, uarg, _IOC_SIZE(cmd)))
                return -EFAULT;
 
        return 0;
@@ -388,8 +398,8 @@ static long copy_arg_from_user(void *karg, void __user *uarg, unsigned int cmd)
 
 static long copy_arg_to_user(void __user *uarg, void *karg, unsigned int cmd)
 {
-       /* All media IOCTLs are _IOWR() */
-       if (copy_to_user(uarg, karg, _IOC_SIZE(cmd)))
+       if ((_IOC_DIR(cmd) & _IOC_READ) &&
+           copy_to_user(uarg, karg, _IOC_SIZE(cmd)))
                return -EFAULT;
 
        return 0;
@@ -425,6 +435,7 @@ static const struct media_ioctl_info ioctl_info[] = {
        MEDIA_IOC(ENUM_LINKS, media_device_enum_links, MEDIA_IOC_FL_GRAPH_MUTEX),
        MEDIA_IOC(SETUP_LINK, media_device_setup_link, MEDIA_IOC_FL_GRAPH_MUTEX),
        MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX),
+       MEDIA_IOC(REQUEST_ALLOC, media_device_request_alloc, 0),
 };
 
 static long media_device_ioctl(struct file *filp, unsigned int cmd,
@@ -691,9 +702,13 @@ void media_device_init(struct media_device *mdev)
        INIT_LIST_HEAD(&mdev->pads);
        INIT_LIST_HEAD(&mdev->links);
        INIT_LIST_HEAD(&mdev->entity_notify);
+
+       mutex_init(&mdev->req_queue_mutex);
        mutex_init(&mdev->graph_mutex);
        ida_init(&mdev->entity_internal_idx);
 
+       atomic_set(&mdev->request_id, 0);
+
        dev_dbg(mdev->dev, "Media device initialized\n");
 }
 EXPORT_SYMBOL_GPL(media_device_init);
@@ -704,6 +719,7 @@ void media_device_cleanup(struct media_device *mdev)
        mdev->entity_internal_idx_max = 0;
        media_graph_walk_cleanup(&mdev->pm_count_walk);
        mutex_destroy(&mdev->graph_mutex);
+       mutex_destroy(&mdev->req_queue_mutex);
 }
 EXPORT_SYMBOL_GPL(media_device_cleanup);