summaryrefslogtreecommitdiff
path: root/include/media/media-device.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/media/media-device.h')
-rw-r--r--include/media/media-device.h125
1 files changed, 79 insertions, 46 deletions
diff --git a/include/media/media-device.h b/include/media/media-device.h
index 6896266031b9..53d2a16a70b0 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Media device
*
@@ -5,15 +6,6 @@
*
* Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
* Sakari Ailus <sakari.ailus@iki.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef _MEDIA_DEVICE_H
@@ -21,12 +13,14 @@
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
#include <media/media-devnode.h>
#include <media/media-entity.h>
struct ida;
-struct device;
+struct media_device;
/**
* struct media_entity_notify - Media Entity Notify
@@ -50,10 +44,32 @@ struct media_entity_notify {
* struct media_device_ops - Media device operations
* @link_notify: Link state change notification callback. This callback is
* called with the graph_mutex held.
+ * @req_alloc: Allocate a request. Set this if you need to allocate a struct
+ * larger then struct media_request. @req_alloc and @req_free must
+ * either both be set or both be NULL.
+ * @req_free: Free a request. Set this if @req_alloc was set as well, leave
+ * to NULL otherwise.
+ * @req_validate: Validate a request, but do not queue yet. The req_queue_mutex
+ * lock is held when this op is called.
+ * @req_queue: Queue a validated request, cannot fail. If something goes
+ * wrong when queueing this request then it should be marked
+ * as such internally in the driver and any related buffers
+ * must eventually return to vb2 with state VB2_BUF_STATE_ERROR.
+ * The req_queue_mutex lock is held when this op is called.
+ * It is important that vb2 buffer objects are queued last after
+ * all other object types are queued: queueing a buffer kickstarts
+ * the request processing, so all other objects related to the
+ * request (and thus the buffer) must be available to the driver.
+ * And once a buffer is queued, then the driver can complete
+ * or delete objects from the request before req_queue exits.
*/
struct media_device_ops {
int (*link_notify)(struct media_link *link, u32 flags,
unsigned int notification);
+ struct media_request *(*req_alloc)(struct media_device *mdev);
+ void (*req_free)(struct media_request *req);
+ int (*req_validate)(struct media_request *req);
+ void (*req_queue)(struct media_request *req);
};
/**
@@ -68,7 +84,6 @@ struct media_device_ops {
* @serial: Device serial number (optional)
* @bus_info: Unique and stable device location identifier
* @hw_revision: Hardware device revision
- * @driver_version: Device driver version
* @topology_version: Monotonic counter for storing the version of the graph
* topology. Should be incremented each time the topology changes.
* @id: Unique ID used on the last registered graph object
@@ -89,6 +104,9 @@ struct media_device_ops {
* @disable_source: Disable Source Handler function pointer
*
* @ops: Operation handler callbacks
+ * @req_queue_mutex: Serialise the MEDIA_REQUEST_IOC_QUEUE ioctl w.r.t.
+ * other operations that stop or start streaming.
+ * @request_id: Used to generate unique request IDs
*
* This structure represents an abstract high-level media device. It allows easy
* access to entities and provides basic media device-level support. The
@@ -111,7 +129,7 @@ struct media_device_ops {
*
* Use-case: find tuner entity connected to the decoder
* entity and check if it is available, and activate the
- * the link between them from @enable_source and deactivate
+ * link between them from @enable_source and deactivate
* from @disable_source.
*
* .. note::
@@ -134,7 +152,6 @@ struct media_device {
char serial[40];
char bus_info[32];
u32 hw_revision;
- u32 driver_version;
u64 topology_version;
@@ -160,10 +177,12 @@ struct media_device {
void (*disable_source)(struct media_entity *entity);
const struct media_device_ops *ops;
+
+ struct mutex req_queue_mutex;
+ atomic_t request_id;
};
-/* We don't need to include pci.h or usb.h here */
-struct pci_dev;
+/* We don't need to include usb.h here */
struct usb_device;
#ifdef CONFIG_MEDIA_CONTROLLER
@@ -173,21 +192,6 @@ struct usb_device;
#define MEDIA_DEV_NOTIFY_POST_LINK_CH 1
/**
- * media_entity_enum_init - Initialise an entity enumeration
- *
- * @ent_enum: Entity enumeration to be initialised
- * @mdev: The related media device
- *
- * Return: zero on success or a negative error code.
- */
-static inline __must_check int media_entity_enum_init(
- struct media_entity_enum *ent_enum, struct media_device *mdev)
-{
- return __media_entity_enum_init(ent_enum,
- mdev->entity_internal_idx_max + 1);
-}
-
-/**
* media_device_init() - Initializes a media device element
*
* @mdev: pointer to struct &media_device
@@ -200,6 +204,15 @@ static inline __must_check int media_entity_enum_init(
* So drivers need to first initialize the media device, register any entity
* within the media device, create pad to pad links and then finally register
* the media device by calling media_device_register() as a final step.
+ *
+ * The caller is responsible for initializing the media device before
+ * registration. The following fields must be set:
+ *
+ * - dev must point to the parent device
+ * - model must be filled with the device model name
+ *
+ * The bus_info field is set by media_device_init() for PCI and platform devices
+ * if the field begins with '\0'.
*/
void media_device_init(struct media_device *mdev);
@@ -224,36 +237,28 @@ void media_device_cleanup(struct media_device *mdev);
* The caller is responsible for initializing the &media_device structure
* before registration. The following fields of &media_device must be set:
*
- * - &media_entity.dev must point to the parent device (usually a &pci_dev,
- * &usb_interface or &platform_device instance).
- *
- * - &media_entity.model must be filled with the device model name as a
+ * - &media_device.model must be filled with the device model name as a
* NUL-terminated UTF-8 string. The device/model revision must not be
* stored in this field.
*
* The following fields are optional:
*
- * - &media_entity.serial is a unique serial number stored as a
+ * - &media_device.serial is a unique serial number stored as a
* NUL-terminated ASCII string. The field is big enough to store a GUID
* in text form. If the hardware doesn't provide a unique serial number
* this field must be left empty.
*
- * - &media_entity.bus_info represents the location of the device in the
+ * - &media_device.bus_info represents the location of the device in the
* system as a NUL-terminated ASCII string. For PCI/PCIe devices
- * &media_entity.bus_info must be set to "PCI:" (or "PCIe:") followed by
+ * &media_device.bus_info must be set to "PCI:" (or "PCIe:") followed by
* the value of pci_name(). For USB devices,the usb_make_path() function
* must be used. This field is used by applications to distinguish between
* otherwise identical devices that don't provide a serial number.
*
- * - &media_entity.hw_revision is the hardware device revision in a
+ * - &media_device.hw_revision is the hardware device revision in a
* driver-specific format. When possible the revision should be formatted
* with the KERNEL_VERSION() macro.
*
- * - &media_entity.driver_version is formatted with the KERNEL_VERSION()
- * macro. The version minor must be incremented when new features are added
- * to the userspace API without breaking binary compatibility. The version
- * major must be incremented when binary compatibility is broken.
- *
* .. note::
*
* #) Upon successful registration a character device named media[0-9]+ is created. The device major and minor numbers are dynamic. The model name is exported as a sysfs attribute.
@@ -359,7 +364,7 @@ void media_device_unregister_entity(struct media_entity *entity);
* media_entity_notify callbacks are invoked.
*/
-int __must_check media_device_register_entity_notify(struct media_device *mdev,
+void media_device_register_entity_notify(struct media_device *mdev,
struct media_entity_notify *nptr);
/**
@@ -424,6 +429,9 @@ void __media_device_usb_init(struct media_device *mdev,
const char *driver_name);
#else
+static inline void media_device_init(struct media_device *mdev)
+{
+}
static inline int media_device_register(struct media_device *mdev)
{
return 0;
@@ -431,6 +439,9 @@ static inline int media_device_register(struct media_device *mdev)
static inline void media_device_unregister(struct media_device *mdev)
{
}
+static inline void media_device_cleanup(struct media_device *mdev)
+{
+}
static inline int media_device_register_entity(struct media_device *mdev,
struct media_entity *entity)
{
@@ -439,11 +450,10 @@ static inline int media_device_register_entity(struct media_device *mdev,
static inline void media_device_unregister_entity(struct media_entity *entity)
{
}
-static inline int media_device_register_entity_notify(
+static inline void media_device_register_entity_notify(
struct media_device *mdev,
struct media_entity_notify *nptr)
{
- return 0;
}
static inline void media_device_unregister_entity_notify(
struct media_device *mdev,
@@ -482,4 +492,27 @@ static inline void __media_device_usb_init(struct media_device *mdev,
#define media_device_usb_init(mdev, udev, name) \
__media_device_usb_init(mdev, udev, name, KBUILD_MODNAME)
+/**
+ * media_set_bus_info() - Set bus_info field
+ *
+ * @bus_info: Variable where to write the bus info (char array)
+ * @bus_info_size: Length of the bus_info
+ * @dev: Related struct device
+ *
+ * Sets bus information based on &dev. This is currently done for PCI and
+ * platform devices. dev is required to be non-NULL for this to happen.
+ *
+ * This function is not meant to be called from drivers.
+ */
+static inline void
+media_set_bus_info(char *bus_info, size_t bus_info_size, struct device *dev)
+{
+ if (!dev)
+ strscpy(bus_info, "no bus info", bus_info_size);
+ else if (dev_is_platform(dev))
+ snprintf(bus_info, bus_info_size, "platform:%s", dev_name(dev));
+ else if (dev_is_pci(dev))
+ snprintf(bus_info, bus_info_size, "PCI:%s", dev_name(dev));
+}
+
#endif