1ff768f59SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
2ff768f59SMauro Carvalho Chehab
3ff768f59SMauro Carvalho ChehabMedia Controller devices
4ff768f59SMauro Carvalho Chehab------------------------
5ff768f59SMauro Carvalho Chehab
6ff768f59SMauro Carvalho ChehabMedia Controller
7ff768f59SMauro Carvalho Chehab~~~~~~~~~~~~~~~~
8ff768f59SMauro Carvalho Chehab
9ff768f59SMauro Carvalho ChehabThe media controller userspace API is documented in
10ff768f59SMauro Carvalho Chehab:ref:`the Media Controller uAPI book <media_controller>`. This document focus
11ff768f59SMauro Carvalho Chehabon the kernel-side implementation of the media framework.
12ff768f59SMauro Carvalho Chehab
13ff768f59SMauro Carvalho ChehabAbstract media device model
14ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^
15ff768f59SMauro Carvalho Chehab
16ff768f59SMauro Carvalho ChehabDiscovering a device internal topology, and configuring it at runtime, is one
17ff768f59SMauro Carvalho Chehabof the goals of the media framework. To achieve this, hardware devices are
18ff768f59SMauro Carvalho Chehabmodelled as an oriented graph of building blocks called entities connected
19ff768f59SMauro Carvalho Chehabthrough pads.
20ff768f59SMauro Carvalho Chehab
21ff768f59SMauro Carvalho ChehabAn entity is a basic media hardware building block. It can correspond to
22ff768f59SMauro Carvalho Chehaba large variety of logical blocks such as physical hardware devices
23ff768f59SMauro Carvalho Chehab(CMOS sensor for instance), logical hardware devices (a building block
24ff768f59SMauro Carvalho Chehabin a System-on-Chip image processing pipeline), DMA channels or physical
25ff768f59SMauro Carvalho Chehabconnectors.
26ff768f59SMauro Carvalho Chehab
27ff768f59SMauro Carvalho ChehabA pad is a connection endpoint through which an entity can interact with
28ff768f59SMauro Carvalho Chehabother entities. Data (not restricted to video) produced by an entity
29ff768f59SMauro Carvalho Chehabflows from the entity's output to one or more entity inputs. Pads should
30ff768f59SMauro Carvalho Chehabnot be confused with physical pins at chip boundaries.
31ff768f59SMauro Carvalho Chehab
32ff768f59SMauro Carvalho ChehabA link is a point-to-point oriented connection between two pads, either
33ff768f59SMauro Carvalho Chehabon the same entity or on different entities. Data flows from a source
34ff768f59SMauro Carvalho Chehabpad to a sink pad.
35ff768f59SMauro Carvalho Chehab
36ff768f59SMauro Carvalho ChehabMedia device
37ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^
38ff768f59SMauro Carvalho Chehab
399303c9d5SMauro Carvalho ChehabA media device is represented by a struct media_device
40ff768f59SMauro Carvalho Chehabinstance, defined in ``include/media/media-device.h``.
41ff768f59SMauro Carvalho ChehabAllocation of the structure is handled by the media device driver, usually by
42ff768f59SMauro Carvalho Chehabembedding the :c:type:`media_device` instance in a larger driver-specific
43ff768f59SMauro Carvalho Chehabstructure.
44ff768f59SMauro Carvalho Chehab
45*1d1d8669SSakari AilusDrivers initialise media device instances by calling
46*1d1d8669SSakari Ailus:c:func:`media_device_init()`. After initialising a media device instance, it is
47*1d1d8669SSakari Ailusregistered by calling :c:func:`__media_device_register()` via the macro
48*1d1d8669SSakari Ailus``media_device_register()`` and unregistered by calling
49*1d1d8669SSakari Ailus:c:func:`media_device_unregister()`. An initialised media device must be
50*1d1d8669SSakari Ailuseventually cleaned up by calling :c:func:`media_device_cleanup()`.
51*1d1d8669SSakari Ailus
52*1d1d8669SSakari AilusNote that it is not allowed to unregister a media device instance that was not
53*1d1d8669SSakari Ailuspreviously registered, or clean up a media device instance that was not
54*1d1d8669SSakari Ailuspreviously initialised.
55ff768f59SMauro Carvalho Chehab
56ff768f59SMauro Carvalho ChehabEntities
57ff768f59SMauro Carvalho Chehab^^^^^^^^
58ff768f59SMauro Carvalho Chehab
599303c9d5SMauro Carvalho ChehabEntities are represented by a struct media_entity
60ff768f59SMauro Carvalho Chehabinstance, defined in ``include/media/media-entity.h``. The structure is usually
61ff768f59SMauro Carvalho Chehabembedded into a higher-level structure, such as
62ff768f59SMauro Carvalho Chehab:c:type:`v4l2_subdev` or :c:type:`video_device`
63ff768f59SMauro Carvalho Chehabinstances, although drivers can allocate entities directly.
64ff768f59SMauro Carvalho Chehab
65ff768f59SMauro Carvalho ChehabDrivers initialize entity pads by calling
66ff768f59SMauro Carvalho Chehab:c:func:`media_entity_pads_init()`.
67ff768f59SMauro Carvalho Chehab
68ff768f59SMauro Carvalho ChehabDrivers register entities with a media device by calling
69ff768f59SMauro Carvalho Chehab:c:func:`media_device_register_entity()`
70ff768f59SMauro Carvalho Chehaband unregistered by calling
71ff768f59SMauro Carvalho Chehab:c:func:`media_device_unregister_entity()`.
72ff768f59SMauro Carvalho Chehab
73ff768f59SMauro Carvalho ChehabInterfaces
74ff768f59SMauro Carvalho Chehab^^^^^^^^^^
75ff768f59SMauro Carvalho Chehab
76ff768f59SMauro Carvalho ChehabInterfaces are represented by a
779303c9d5SMauro Carvalho Chehabstruct media_interface instance, defined in
78ff768f59SMauro Carvalho Chehab``include/media/media-entity.h``. Currently, only one type of interface is
79ff768f59SMauro Carvalho Chehabdefined: a device node. Such interfaces are represented by a
809303c9d5SMauro Carvalho Chehabstruct media_intf_devnode.
81ff768f59SMauro Carvalho Chehab
82ff768f59SMauro Carvalho ChehabDrivers initialize and create device node interfaces by calling
83ff768f59SMauro Carvalho Chehab:c:func:`media_devnode_create()`
84ff768f59SMauro Carvalho Chehaband remove them by calling:
85ff768f59SMauro Carvalho Chehab:c:func:`media_devnode_remove()`.
86ff768f59SMauro Carvalho Chehab
87ff768f59SMauro Carvalho ChehabPads
88ff768f59SMauro Carvalho Chehab^^^^
899303c9d5SMauro Carvalho ChehabPads are represented by a struct media_pad instance,
90ff768f59SMauro Carvalho Chehabdefined in ``include/media/media-entity.h``. Each entity stores its pads in
91ff768f59SMauro Carvalho Chehaba pads array managed by the entity driver. Drivers usually embed the array in
92ff768f59SMauro Carvalho Chehaba driver-specific structure.
93ff768f59SMauro Carvalho Chehab
94ff768f59SMauro Carvalho ChehabPads are identified by their entity and their 0-based index in the pads
95ff768f59SMauro Carvalho Chehabarray.
96ff768f59SMauro Carvalho Chehab
979303c9d5SMauro Carvalho ChehabBoth information are stored in the struct media_pad,
989303c9d5SMauro Carvalho Chehabmaking the struct media_pad pointer the canonical way
99ff768f59SMauro Carvalho Chehabto store and pass link references.
100ff768f59SMauro Carvalho Chehab
101ff768f59SMauro Carvalho ChehabPads have flags that describe the pad capabilities and state.
102ff768f59SMauro Carvalho Chehab
103ff768f59SMauro Carvalho Chehab``MEDIA_PAD_FL_SINK`` indicates that the pad supports sinking data.
104ff768f59SMauro Carvalho Chehab``MEDIA_PAD_FL_SOURCE`` indicates that the pad supports sourcing data.
105ff768f59SMauro Carvalho Chehab
106ff768f59SMauro Carvalho Chehab.. note::
107ff768f59SMauro Carvalho Chehab
108ff768f59SMauro Carvalho Chehab  One and only one of ``MEDIA_PAD_FL_SINK`` or ``MEDIA_PAD_FL_SOURCE`` must
109ff768f59SMauro Carvalho Chehab  be set for each pad.
110ff768f59SMauro Carvalho Chehab
111ff768f59SMauro Carvalho ChehabLinks
112ff768f59SMauro Carvalho Chehab^^^^^
113ff768f59SMauro Carvalho Chehab
1149303c9d5SMauro Carvalho ChehabLinks are represented by a struct media_link instance,
115ff768f59SMauro Carvalho Chehabdefined in ``include/media/media-entity.h``. There are two types of links:
116ff768f59SMauro Carvalho Chehab
117ff768f59SMauro Carvalho Chehab**1. pad to pad links**:
118ff768f59SMauro Carvalho Chehab
119ff768f59SMauro Carvalho ChehabAssociate two entities via their PADs. Each entity has a list that points
120ff768f59SMauro Carvalho Chehabto all links originating at or targeting any of its pads.
121ff768f59SMauro Carvalho ChehabA given link is thus stored twice, once in the source entity and once in
122ff768f59SMauro Carvalho Chehabthe target entity.
123ff768f59SMauro Carvalho Chehab
124ff768f59SMauro Carvalho ChehabDrivers create pad to pad links by calling:
125ff768f59SMauro Carvalho Chehab:c:func:`media_create_pad_link()` and remove with
126ff768f59SMauro Carvalho Chehab:c:func:`media_entity_remove_links()`.
127ff768f59SMauro Carvalho Chehab
128ff768f59SMauro Carvalho Chehab**2. interface to entity links**:
129ff768f59SMauro Carvalho Chehab
130ff768f59SMauro Carvalho ChehabAssociate one interface to a Link.
131ff768f59SMauro Carvalho Chehab
132ff768f59SMauro Carvalho ChehabDrivers create interface to entity links by calling:
133ff768f59SMauro Carvalho Chehab:c:func:`media_create_intf_link()` and remove with
134ff768f59SMauro Carvalho Chehab:c:func:`media_remove_intf_links()`.
135ff768f59SMauro Carvalho Chehab
136ff768f59SMauro Carvalho Chehab.. note::
137ff768f59SMauro Carvalho Chehab
138ff768f59SMauro Carvalho Chehab   Links can only be created after having both ends already created.
139ff768f59SMauro Carvalho Chehab
140ff768f59SMauro Carvalho ChehabLinks have flags that describe the link capabilities and state. The
141ff768f59SMauro Carvalho Chehabvalid values are described at :c:func:`media_create_pad_link()` and
142ff768f59SMauro Carvalho Chehab:c:func:`media_create_intf_link()`.
143ff768f59SMauro Carvalho Chehab
144ff768f59SMauro Carvalho ChehabGraph traversal
145ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^^^^
146ff768f59SMauro Carvalho Chehab
147ff768f59SMauro Carvalho ChehabThe media framework provides APIs to iterate over entities in a graph.
148ff768f59SMauro Carvalho Chehab
149ff768f59SMauro Carvalho ChehabTo iterate over all entities belonging to a media device, drivers can use
150ff768f59SMauro Carvalho Chehabthe media_device_for_each_entity macro, defined in
151ff768f59SMauro Carvalho Chehab``include/media/media-device.h``.
152ff768f59SMauro Carvalho Chehab
153ff768f59SMauro Carvalho Chehab..  code-block:: c
154ff768f59SMauro Carvalho Chehab
155ff768f59SMauro Carvalho Chehab    struct media_entity *entity;
156ff768f59SMauro Carvalho Chehab
157ff768f59SMauro Carvalho Chehab    media_device_for_each_entity(entity, mdev) {
158ff768f59SMauro Carvalho Chehab    // entity will point to each entity in turn
159ff768f59SMauro Carvalho Chehab    ...
160ff768f59SMauro Carvalho Chehab    }
161ff768f59SMauro Carvalho Chehab
162ff768f59SMauro Carvalho ChehabDrivers might also need to iterate over all entities in a graph that can be
163ff768f59SMauro Carvalho Chehabreached only through enabled links starting at a given entity. The media
164ff768f59SMauro Carvalho Chehabframework provides a depth-first graph traversal API for that purpose.
165ff768f59SMauro Carvalho Chehab
166ff768f59SMauro Carvalho Chehab.. note::
167ff768f59SMauro Carvalho Chehab
168ff768f59SMauro Carvalho Chehab   Graphs with cycles (whether directed or undirected) are **NOT**
169ff768f59SMauro Carvalho Chehab   supported by the graph traversal API. To prevent infinite loops, the graph
170ff768f59SMauro Carvalho Chehab   traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
171ff768f59SMauro Carvalho Chehab   currently defined as 16.
172ff768f59SMauro Carvalho Chehab
173ff768f59SMauro Carvalho ChehabDrivers initiate a graph traversal by calling
174ff768f59SMauro Carvalho Chehab:c:func:`media_graph_walk_start()`
175ff768f59SMauro Carvalho Chehab
176ff768f59SMauro Carvalho ChehabThe graph structure, provided by the caller, is initialized to start graph
177ff768f59SMauro Carvalho Chehabtraversal at the given entity.
178ff768f59SMauro Carvalho Chehab
179ff768f59SMauro Carvalho ChehabDrivers can then retrieve the next entity by calling
180ff768f59SMauro Carvalho Chehab:c:func:`media_graph_walk_next()`
181ff768f59SMauro Carvalho Chehab
182ff768f59SMauro Carvalho ChehabWhen the graph traversal is complete the function will return ``NULL``.
183ff768f59SMauro Carvalho Chehab
184ff768f59SMauro Carvalho ChehabGraph traversal can be interrupted at any moment. No cleanup function call
185ff768f59SMauro Carvalho Chehabis required and the graph structure can be freed normally.
186ff768f59SMauro Carvalho Chehab
187ff768f59SMauro Carvalho ChehabHelper functions can be used to find a link between two given pads, or a pad
188ff768f59SMauro Carvalho Chehabconnected to another pad through an enabled link
189ff768f59SMauro Carvalho Chehab:c:func:`media_entity_find_link()` and
190ff768f59SMauro Carvalho Chehab:c:func:`media_entity_remote_pad()`.
191ff768f59SMauro Carvalho Chehab
192ff768f59SMauro Carvalho ChehabUse count and power handling
193ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^
194ff768f59SMauro Carvalho Chehab
195ff768f59SMauro Carvalho ChehabDue to the wide differences between drivers regarding power management
196ff768f59SMauro Carvalho Chehabneeds, the media controller does not implement power management. However,
1979303c9d5SMauro Carvalho Chehabthe struct media_entity includes a ``use_count``
198ff768f59SMauro Carvalho Chehabfield that media drivers
199ff768f59SMauro Carvalho Chehabcan use to track the number of users of every entity for power management
200ff768f59SMauro Carvalho Chehabneeds.
201ff768f59SMauro Carvalho Chehab
202ff768f59SMauro Carvalho ChehabThe :c:type:`media_entity<media_entity>`.\ ``use_count`` field is owned by
203ff768f59SMauro Carvalho Chehabmedia drivers and must not be
204ff768f59SMauro Carvalho Chehabtouched by entity drivers. Access to the field must be protected by the
205ff768f59SMauro Carvalho Chehab:c:type:`media_device`.\ ``graph_mutex`` lock.
206ff768f59SMauro Carvalho Chehab
207ff768f59SMauro Carvalho ChehabLinks setup
208ff768f59SMauro Carvalho Chehab^^^^^^^^^^^
209ff768f59SMauro Carvalho Chehab
210ff768f59SMauro Carvalho ChehabLink properties can be modified at runtime by calling
211ff768f59SMauro Carvalho Chehab:c:func:`media_entity_setup_link()`.
212ff768f59SMauro Carvalho Chehab
213ff768f59SMauro Carvalho ChehabPipelines and media streams
214ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^
215ff768f59SMauro Carvalho Chehab
216ff768f59SMauro Carvalho ChehabWhen starting streaming, drivers must notify all entities in the pipeline to
217ff768f59SMauro Carvalho Chehabprevent link states from being modified during streaming by calling
218ff768f59SMauro Carvalho Chehab:c:func:`media_pipeline_start()`.
219ff768f59SMauro Carvalho Chehab
220ff768f59SMauro Carvalho ChehabThe function will mark all entities connected to the given entity through
221ff768f59SMauro Carvalho Chehabenabled links, either directly or indirectly, as streaming.
222ff768f59SMauro Carvalho Chehab
2239303c9d5SMauro Carvalho ChehabThe struct media_pipeline instance pointed to by
224ff768f59SMauro Carvalho Chehabthe pipe argument will be stored in every entity in the pipeline.
2259303c9d5SMauro Carvalho ChehabDrivers should embed the struct media_pipeline
226ff768f59SMauro Carvalho Chehabin higher-level pipeline structures and can then access the
2279303c9d5SMauro Carvalho Chehabpipeline through the struct media_entity
228ff768f59SMauro Carvalho Chehabpipe field.
229ff768f59SMauro Carvalho Chehab
230ff768f59SMauro Carvalho ChehabCalls to :c:func:`media_pipeline_start()` can be nested.
231ff768f59SMauro Carvalho ChehabThe pipeline pointer must be identical for all nested calls to the function.
232ff768f59SMauro Carvalho Chehab
233ff768f59SMauro Carvalho Chehab:c:func:`media_pipeline_start()` may return an error. In that case,
234ff768f59SMauro Carvalho Chehabit will clean up any of the changes it did by itself.
235ff768f59SMauro Carvalho Chehab
236ff768f59SMauro Carvalho ChehabWhen stopping the stream, drivers must notify the entities with
237ff768f59SMauro Carvalho Chehab:c:func:`media_pipeline_stop()`.
238ff768f59SMauro Carvalho Chehab
239ff768f59SMauro Carvalho ChehabIf multiple calls to :c:func:`media_pipeline_start()` have been
240ff768f59SMauro Carvalho Chehabmade the same number of :c:func:`media_pipeline_stop()` calls
241ff768f59SMauro Carvalho Chehabare required to stop streaming.
242ff768f59SMauro Carvalho ChehabThe :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
243ff768f59SMauro Carvalho Chehabnested stop call.
244ff768f59SMauro Carvalho Chehab
245ff768f59SMauro Carvalho ChehabLink configuration will fail with ``-EBUSY`` by default if either end of the
246ff768f59SMauro Carvalho Chehablink is a streaming entity. Links that can be modified while streaming must
247ff768f59SMauro Carvalho Chehabbe marked with the ``MEDIA_LNK_FL_DYNAMIC`` flag.
248ff768f59SMauro Carvalho Chehab
249ff768f59SMauro Carvalho ChehabIf other operations need to be disallowed on streaming entities (such as
250ff768f59SMauro Carvalho Chehabchanging entities configuration parameters) drivers can explicitly check the
251ff768f59SMauro Carvalho Chehabmedia_entity stream_count field to find out if an entity is streaming. This
252ff768f59SMauro Carvalho Chehaboperation must be done with the media_device graph_mutex held.
253ff768f59SMauro Carvalho Chehab
254ff768f59SMauro Carvalho ChehabLink validation
255ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^^^^
256ff768f59SMauro Carvalho Chehab
257ff768f59SMauro Carvalho ChehabLink validation is performed by :c:func:`media_pipeline_start()`
258ff768f59SMauro Carvalho Chehabfor any entity which has sink pads in the pipeline. The
259ff768f59SMauro Carvalho Chehab:c:type:`media_entity`.\ ``link_validate()`` callback is used for that
260ff768f59SMauro Carvalho Chehabpurpose. In ``link_validate()`` callback, entity driver should check
261ff768f59SMauro Carvalho Chehabthat the properties of the source pad of the connected entity and its own
262ff768f59SMauro Carvalho Chehabsink pad match. It is up to the type of the entity (and in the end, the
263ff768f59SMauro Carvalho Chehabproperties of the hardware) what matching actually means.
264ff768f59SMauro Carvalho Chehab
265ff768f59SMauro Carvalho ChehabSubsystems should facilitate link validation by providing subsystem specific
266ff768f59SMauro Carvalho Chehabhelper functions to provide easy access for commonly needed information, and
267ff768f59SMauro Carvalho Chehabin the end provide a way to use driver-specific callbacks.
268ff768f59SMauro Carvalho Chehab
269ff768f59SMauro Carvalho ChehabMedia Controller Device Allocator API
270ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
271ff768f59SMauro Carvalho Chehab
272ff768f59SMauro Carvalho ChehabWhen the media device belongs to more than one driver, the shared media
273ff768f59SMauro Carvalho Chehabdevice is allocated with the shared struct device as the key for look ups.
274ff768f59SMauro Carvalho Chehab
275ff768f59SMauro Carvalho ChehabThe shared media device should stay in registered state until the last
276ff768f59SMauro Carvalho Chehabdriver unregisters it. In addition, the media device should be released when
277ff768f59SMauro Carvalho Chehaball the references are released. Each driver gets a reference to the media
278ff768f59SMauro Carvalho Chehabdevice during probe, when it allocates the media device. If media device is
279ff768f59SMauro Carvalho Chehabalready allocated, the allocate API bumps up the refcount and returns the
280ff768f59SMauro Carvalho Chehabexisting media device. The driver puts the reference back in its disconnect
281ff768f59SMauro Carvalho Chehabroutine when it calls :c:func:`media_device_delete()`.
282ff768f59SMauro Carvalho Chehab
283ff768f59SMauro Carvalho ChehabThe media device is unregistered and cleaned up from the kref put handler to
284ff768f59SMauro Carvalho Chehabensure that the media device stays in registered state until the last driver
285ff768f59SMauro Carvalho Chehabunregisters the media device.
286ff768f59SMauro Carvalho Chehab
287ff768f59SMauro Carvalho Chehab**Driver Usage**
288ff768f59SMauro Carvalho Chehab
289ff768f59SMauro Carvalho ChehabDrivers should use the appropriate media-core routines to manage the shared
290ff768f59SMauro Carvalho Chehabmedia device life-time handling the two states:
291ff768f59SMauro Carvalho Chehab1. allocate -> register -> delete
292ff768f59SMauro Carvalho Chehab2. get reference to already registered device -> delete
293ff768f59SMauro Carvalho Chehab
294ff768f59SMauro Carvalho Chehabcall :c:func:`media_device_delete()` routine to make sure the shared media
295ff768f59SMauro Carvalho Chehabdevice delete is handled correctly.
296ff768f59SMauro Carvalho Chehab
297ff768f59SMauro Carvalho Chehab**driver probe:**
298ff768f59SMauro Carvalho ChehabCall :c:func:`media_device_usb_allocate()` to allocate or get a reference
299ff768f59SMauro Carvalho ChehabCall :c:func:`media_device_register()`, if media devnode isn't registered
300ff768f59SMauro Carvalho Chehab
301ff768f59SMauro Carvalho Chehab**driver disconnect:**
302ff768f59SMauro Carvalho ChehabCall :c:func:`media_device_delete()` to free the media_device. Freeing is
303ff768f59SMauro Carvalho Chehabhandled by the kref put handler.
304ff768f59SMauro Carvalho Chehab
305ff768f59SMauro Carvalho ChehabAPI Definitions
306ff768f59SMauro Carvalho Chehab^^^^^^^^^^^^^^^
307ff768f59SMauro Carvalho Chehab
308ff768f59SMauro Carvalho Chehab.. kernel-doc:: include/media/media-device.h
309ff768f59SMauro Carvalho Chehab
310ff768f59SMauro Carvalho Chehab.. kernel-doc:: include/media/media-devnode.h
311ff768f59SMauro Carvalho Chehab
312ff768f59SMauro Carvalho Chehab.. kernel-doc:: include/media/media-entity.h
313ff768f59SMauro Carvalho Chehab
314ff768f59SMauro Carvalho Chehab.. kernel-doc:: include/media/media-request.h
315ff768f59SMauro Carvalho Chehab
316ff768f59SMauro Carvalho Chehab.. kernel-doc:: include/media/media-dev-allocator.h
317