Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Media device node
0004  *
0005  * Copyright (C) 2010 Nokia Corporation
0006  *
0007  * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
0008  *       Sakari Ailus <sakari.ailus@iki.fi>
0009  *
0010  * --
0011  *
0012  * Common functions for media-related drivers to register and unregister media
0013  * device nodes.
0014  */
0015 
0016 #ifndef _MEDIA_DEVNODE_H
0017 #define _MEDIA_DEVNODE_H
0018 
0019 #include <linux/poll.h>
0020 #include <linux/fs.h>
0021 #include <linux/device.h>
0022 #include <linux/cdev.h>
0023 
0024 struct media_device;
0025 
0026 /*
0027  * Flag to mark the media_devnode struct as registered. Drivers must not touch
0028  * this flag directly, it will be set and cleared by media_devnode_register and
0029  * media_devnode_unregister.
0030  */
0031 #define MEDIA_FLAG_REGISTERED   0
0032 
0033 /**
0034  * struct media_file_operations - Media device file operations
0035  *
0036  * @owner: should be filled with %THIS_MODULE
0037  * @read: pointer to the function that implements read() syscall
0038  * @write: pointer to the function that implements write() syscall
0039  * @poll: pointer to the function that implements poll() syscall
0040  * @ioctl: pointer to the function that implements ioctl() syscall
0041  * @compat_ioctl: pointer to the function that will handle 32 bits userspace
0042  *  calls to the ioctl() syscall on a Kernel compiled with 64 bits.
0043  * @open: pointer to the function that implements open() syscall
0044  * @release: pointer to the function that will release the resources allocated
0045  *  by the @open function.
0046  */
0047 struct media_file_operations {
0048     struct module *owner;
0049     ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
0050     ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
0051     __poll_t (*poll) (struct file *, struct poll_table_struct *);
0052     long (*ioctl) (struct file *, unsigned int, unsigned long);
0053     long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
0054     int (*open) (struct file *);
0055     int (*release) (struct file *);
0056 };
0057 
0058 /**
0059  * struct media_devnode - Media device node
0060  * @media_dev:  pointer to struct &media_device
0061  * @fops:   pointer to struct &media_file_operations with media device ops
0062  * @dev:    pointer to struct &device containing the media controller device
0063  * @cdev:   struct cdev pointer character device
0064  * @parent: parent device
0065  * @minor:  device node minor number
0066  * @flags:  flags, combination of the ``MEDIA_FLAG_*`` constants
0067  * @release:    release callback called at the end of ``media_devnode_release()``
0068  *      routine at media-device.c.
0069  *
0070  * This structure represents a media-related device node.
0071  *
0072  * The @parent is a physical device. It must be set by core or device drivers
0073  * before registering the node.
0074  */
0075 struct media_devnode {
0076     struct media_device *media_dev;
0077 
0078     /* device ops */
0079     const struct media_file_operations *fops;
0080 
0081     /* sysfs */
0082     struct device dev;      /* media device */
0083     struct cdev cdev;       /* character device */
0084     struct device *parent;      /* device parent */
0085 
0086     /* device info */
0087     int minor;
0088     unsigned long flags;        /* Use bitops to access flags */
0089 
0090     /* callbacks */
0091     void (*release)(struct media_devnode *devnode);
0092 };
0093 
0094 /* dev to media_devnode */
0095 #define to_media_devnode(cd) container_of(cd, struct media_devnode, dev)
0096 
0097 /**
0098  * media_devnode_register - register a media device node
0099  *
0100  * @mdev: struct media_device we want to register a device node
0101  * @devnode: media device node structure we want to register
0102  * @owner: should be filled with %THIS_MODULE
0103  *
0104  * The registration code assigns minor numbers and registers the new device node
0105  * with the kernel. An error is returned if no free minor number can be found,
0106  * or if the registration of the device node fails.
0107  *
0108  * Zero is returned on success.
0109  *
0110  * Note that if the media_devnode_register call fails, the release() callback of
0111  * the media_devnode structure is *not* called, so the caller is responsible for
0112  * freeing any data.
0113  */
0114 int __must_check media_devnode_register(struct media_device *mdev,
0115                     struct media_devnode *devnode,
0116                     struct module *owner);
0117 
0118 /**
0119  * media_devnode_unregister_prepare - clear the media device node register bit
0120  * @devnode: the device node to prepare for unregister
0121  *
0122  * This clears the passed device register bit. Future open calls will be met
0123  * with errors. Should be called before media_devnode_unregister() to avoid
0124  * races with unregister and device file open calls.
0125  *
0126  * This function can safely be called if the device node has never been
0127  * registered or has already been unregistered.
0128  */
0129 void media_devnode_unregister_prepare(struct media_devnode *devnode);
0130 
0131 /**
0132  * media_devnode_unregister - unregister a media device node
0133  * @devnode: the device node to unregister
0134  *
0135  * This unregisters the passed device. Future open calls will be met with
0136  * errors.
0137  *
0138  * Should be called after media_devnode_unregister_prepare()
0139  */
0140 void media_devnode_unregister(struct media_devnode *devnode);
0141 
0142 /**
0143  * media_devnode_data - returns a pointer to the &media_devnode
0144  *
0145  * @filp: pointer to struct &file
0146  */
0147 static inline struct media_devnode *media_devnode_data(struct file *filp)
0148 {
0149     return filp->private_data;
0150 }
0151 
0152 /**
0153  * media_devnode_is_registered - returns true if &media_devnode is registered;
0154  *  false otherwise.
0155  *
0156  * @devnode: pointer to struct &media_devnode.
0157  *
0158  * Note: If mdev is NULL, it also returns false.
0159  */
0160 static inline int media_devnode_is_registered(struct media_devnode *devnode)
0161 {
0162     if (!devnode)
0163         return false;
0164 
0165     return test_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
0166 }
0167 
0168 #endif /* _MEDIA_DEVNODE_H */