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-device.rst (5588B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3V4L2 device instance
      4--------------------
      5
      6Each device instance is represented by a struct v4l2_device.
      7Very simple devices can just allocate this struct, but most of the time you
      8would embed this struct inside a larger struct.
      9
     10You must register the device instance by calling:
     11
     12	:c:func:`v4l2_device_register <v4l2_device_register>`
     13	(dev, :c:type:`v4l2_dev <v4l2_device>`).
     14
     15Registration will initialize the :c:type:`v4l2_device` struct. If the
     16dev->driver_data field is ``NULL``, it will be linked to
     17:c:type:`v4l2_dev <v4l2_device>` argument.
     18
     19Drivers that want integration with the media device framework need to set
     20dev->driver_data manually to point to the driver-specific device structure
     21that embed the struct v4l2_device instance. This is achieved by a
     22``dev_set_drvdata()`` call before registering the V4L2 device instance.
     23They must also set the struct v4l2_device mdev field to point to a
     24properly initialized and registered :c:type:`media_device` instance.
     25
     26If :c:type:`v4l2_dev <v4l2_device>`\ ->name is empty then it will be set to a
     27value derived from dev (driver name followed by the bus_id, to be precise).
     28If you set it up before  calling :c:func:`v4l2_device_register` then it will
     29be untouched. If dev is ``NULL``, then you **must** setup
     30:c:type:`v4l2_dev <v4l2_device>`\ ->name before calling
     31:c:func:`v4l2_device_register`.
     32
     33You can use :c:func:`v4l2_device_set_name` to set the name based on a driver
     34name and a driver-global atomic_t instance. This will generate names like
     35``ivtv0``, ``ivtv1``, etc. If the name ends with a digit, then it will insert
     36a dash: ``cx18-0``, ``cx18-1``, etc. This function returns the instance number.
     37
     38The first ``dev`` argument is normally the ``struct device`` pointer of a
     39``pci_dev``, ``usb_interface`` or ``platform_device``. It is rare for dev to
     40be ``NULL``, but it happens with ISA devices or when one device creates
     41multiple PCI devices, thus making it impossible to associate
     42:c:type:`v4l2_dev <v4l2_device>` with a particular parent.
     43
     44You can also supply a ``notify()`` callback that can be called by sub-devices
     45to notify you of events. Whether you need to set this depends on the
     46sub-device. Any notifications a sub-device supports must be defined in a header
     47in ``include/media/subdevice.h``.
     48
     49V4L2 devices are unregistered by calling:
     50
     51	:c:func:`v4l2_device_unregister`
     52	(:c:type:`v4l2_dev <v4l2_device>`).
     53
     54If the dev->driver_data field points to :c:type:`v4l2_dev <v4l2_device>`,
     55it will be reset to ``NULL``. Unregistering will also automatically unregister
     56all subdevs from the device.
     57
     58If you have a hotpluggable device (e.g. a USB device), then when a disconnect
     59happens the parent device becomes invalid. Since :c:type:`v4l2_device` has a
     60pointer to that parent device it has to be cleared as well to mark that the
     61parent is gone. To do this call:
     62
     63	:c:func:`v4l2_device_disconnect`
     64	(:c:type:`v4l2_dev <v4l2_device>`).
     65
     66This does *not* unregister the subdevs, so you still need to call the
     67:c:func:`v4l2_device_unregister` function for that. If your driver is not
     68hotpluggable, then there is no need to call :c:func:`v4l2_device_disconnect`.
     69
     70Sometimes you need to iterate over all devices registered by a specific
     71driver. This is usually the case if multiple device drivers use the same
     72hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
     73hardware. The same is true for alsa drivers for example.
     74
     75You can iterate over all registered devices as follows:
     76
     77.. code-block:: c
     78
     79	static int callback(struct device *dev, void *p)
     80	{
     81		struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
     82
     83		/* test if this device was inited */
     84		if (v4l2_dev == NULL)
     85			return 0;
     86		...
     87		return 0;
     88	}
     89
     90	int iterate(void *p)
     91	{
     92		struct device_driver *drv;
     93		int err;
     94
     95		/* Find driver 'ivtv' on the PCI bus.
     96		pci_bus_type is a global. For USB buses use usb_bus_type. */
     97		drv = driver_find("ivtv", &pci_bus_type);
     98		/* iterate over all ivtv device instances */
     99		err = driver_for_each_device(drv, NULL, p, callback);
    100		put_driver(drv);
    101		return err;
    102	}
    103
    104Sometimes you need to keep a running counter of the device instance. This is
    105commonly used to map a device instance to an index of a module option array.
    106
    107The recommended approach is as follows:
    108
    109.. code-block:: c
    110
    111	static atomic_t drv_instance = ATOMIC_INIT(0);
    112
    113	static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
    114	{
    115		...
    116		state->instance = atomic_inc_return(&drv_instance) - 1;
    117	}
    118
    119If you have multiple device nodes then it can be difficult to know when it is
    120safe to unregister :c:type:`v4l2_device` for hotpluggable devices. For this
    121purpose :c:type:`v4l2_device` has refcounting support. The refcount is
    122increased whenever :c:func:`video_register_device` is called and it is
    123decreased whenever that device node is released. When the refcount reaches
    124zero, then the :c:type:`v4l2_device` release() callback is called. You can
    125do your final cleanup there.
    126
    127If other device nodes (e.g. ALSA) are created, then you can increase and
    128decrease the refcount manually as well by calling:
    129
    130	:c:func:`v4l2_device_get`
    131	(:c:type:`v4l2_dev <v4l2_device>`).
    132
    133or:
    134
    135	:c:func:`v4l2_device_put`
    136	(:c:type:`v4l2_dev <v4l2_device>`).
    137
    138Since the initial refcount is 1 you also need to call
    139:c:func:`v4l2_device_put` in the ``disconnect()`` callback (for USB devices)
    140or in the ``remove()`` callback (for e.g. PCI devices), otherwise the refcount
    141will never reach 0.
    142
    143v4l2_device functions and data structures
    144^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    145
    146.. kernel-doc:: include/media/v4l2-device.h