cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

v4l2-fh.c (2815B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * v4l2-fh.c
      4 *
      5 * V4L2 file handles.
      6 *
      7 * Copyright (C) 2009--2010 Nokia Corporation.
      8 *
      9 * Contact: Sakari Ailus <sakari.ailus@iki.fi>
     10 */
     11
     12#include <linux/bitops.h>
     13#include <linux/slab.h>
     14#include <linux/export.h>
     15#include <media/v4l2-dev.h>
     16#include <media/v4l2-fh.h>
     17#include <media/v4l2-event.h>
     18#include <media/v4l2-ioctl.h>
     19#include <media/v4l2-mc.h>
     20
     21void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
     22{
     23	fh->vdev = vdev;
     24	/* Inherit from video_device. May be overridden by the driver. */
     25	fh->ctrl_handler = vdev->ctrl_handler;
     26	INIT_LIST_HEAD(&fh->list);
     27	set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
     28	/*
     29	 * determine_valid_ioctls() does not know if struct v4l2_fh
     30	 * is used by this driver, but here we do. So enable the
     31	 * prio ioctls here.
     32	 */
     33	set_bit(_IOC_NR(VIDIOC_G_PRIORITY), vdev->valid_ioctls);
     34	set_bit(_IOC_NR(VIDIOC_S_PRIORITY), vdev->valid_ioctls);
     35	fh->prio = V4L2_PRIORITY_UNSET;
     36	init_waitqueue_head(&fh->wait);
     37	INIT_LIST_HEAD(&fh->available);
     38	INIT_LIST_HEAD(&fh->subscribed);
     39	fh->sequence = -1;
     40	mutex_init(&fh->subscribe_lock);
     41}
     42EXPORT_SYMBOL_GPL(v4l2_fh_init);
     43
     44void v4l2_fh_add(struct v4l2_fh *fh)
     45{
     46	unsigned long flags;
     47
     48	v4l2_prio_open(fh->vdev->prio, &fh->prio);
     49	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
     50	list_add(&fh->list, &fh->vdev->fh_list);
     51	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
     52}
     53EXPORT_SYMBOL_GPL(v4l2_fh_add);
     54
     55int v4l2_fh_open(struct file *filp)
     56{
     57	struct video_device *vdev = video_devdata(filp);
     58	struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
     59
     60	filp->private_data = fh;
     61	if (fh == NULL)
     62		return -ENOMEM;
     63	v4l2_fh_init(fh, vdev);
     64	v4l2_fh_add(fh);
     65	return 0;
     66}
     67EXPORT_SYMBOL_GPL(v4l2_fh_open);
     68
     69void v4l2_fh_del(struct v4l2_fh *fh)
     70{
     71	unsigned long flags;
     72
     73	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
     74	list_del_init(&fh->list);
     75	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
     76	v4l2_prio_close(fh->vdev->prio, fh->prio);
     77}
     78EXPORT_SYMBOL_GPL(v4l2_fh_del);
     79
     80void v4l2_fh_exit(struct v4l2_fh *fh)
     81{
     82	if (fh->vdev == NULL)
     83		return;
     84	v4l_disable_media_source(fh->vdev);
     85	v4l2_event_unsubscribe_all(fh);
     86	mutex_destroy(&fh->subscribe_lock);
     87	fh->vdev = NULL;
     88}
     89EXPORT_SYMBOL_GPL(v4l2_fh_exit);
     90
     91int v4l2_fh_release(struct file *filp)
     92{
     93	struct v4l2_fh *fh = filp->private_data;
     94
     95	if (fh) {
     96		v4l2_fh_del(fh);
     97		v4l2_fh_exit(fh);
     98		kfree(fh);
     99		filp->private_data = NULL;
    100	}
    101	return 0;
    102}
    103EXPORT_SYMBOL_GPL(v4l2_fh_release);
    104
    105int v4l2_fh_is_singular(struct v4l2_fh *fh)
    106{
    107	unsigned long flags;
    108	int is_singular;
    109
    110	if (fh == NULL || fh->vdev == NULL)
    111		return 0;
    112	spin_lock_irqsave(&fh->vdev->fh_lock, flags);
    113	is_singular = list_is_singular(&fh->list);
    114	spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
    115	return is_singular;
    116}
    117EXPORT_SYMBOL_GPL(v4l2_fh_is_singular);