xref: /openbmc/linux/include/media/media-devnode.h (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
11802d0beSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2cf4b9211SLaurent Pinchart /*
3cf4b9211SLaurent Pinchart  * Media device node
4cf4b9211SLaurent Pinchart  *
5cf4b9211SLaurent Pinchart  * Copyright (C) 2010 Nokia Corporation
6cf4b9211SLaurent Pinchart  *
7cf4b9211SLaurent Pinchart  * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
8cf4b9211SLaurent Pinchart  *	     Sakari Ailus <sakari.ailus@iki.fi>
9cf4b9211SLaurent Pinchart  *
10cf4b9211SLaurent Pinchart  * --
11cf4b9211SLaurent Pinchart  *
12cf4b9211SLaurent Pinchart  * Common functions for media-related drivers to register and unregister media
13cf4b9211SLaurent Pinchart  * device nodes.
14cf4b9211SLaurent Pinchart  */
15cf4b9211SLaurent Pinchart 
16cf4b9211SLaurent Pinchart #ifndef _MEDIA_DEVNODE_H
17cf4b9211SLaurent Pinchart #define _MEDIA_DEVNODE_H
18cf4b9211SLaurent Pinchart 
19cf4b9211SLaurent Pinchart #include <linux/poll.h>
20cf4b9211SLaurent Pinchart #include <linux/fs.h>
21cf4b9211SLaurent Pinchart #include <linux/device.h>
22cf4b9211SLaurent Pinchart #include <linux/cdev.h>
23cf4b9211SLaurent Pinchart 
24a087ce70SMauro Carvalho Chehab struct media_device;
25a087ce70SMauro Carvalho Chehab 
26cf4b9211SLaurent Pinchart /*
27cf4b9211SLaurent Pinchart  * Flag to mark the media_devnode struct as registered. Drivers must not touch
28cf4b9211SLaurent Pinchart  * this flag directly, it will be set and cleared by media_devnode_register and
29cf4b9211SLaurent Pinchart  * media_devnode_unregister.
30cf4b9211SLaurent Pinchart  */
31cf4b9211SLaurent Pinchart #define MEDIA_FLAG_REGISTERED	0
32cf4b9211SLaurent Pinchart 
3375c7e295SMauro Carvalho Chehab /**
3475c7e295SMauro Carvalho Chehab  * struct media_file_operations - Media device file operations
3575c7e295SMauro Carvalho Chehab  *
3675c7e295SMauro Carvalho Chehab  * @owner: should be filled with %THIS_MODULE
3775c7e295SMauro Carvalho Chehab  * @read: pointer to the function that implements read() syscall
3875c7e295SMauro Carvalho Chehab  * @write: pointer to the function that implements write() syscall
3975c7e295SMauro Carvalho Chehab  * @poll: pointer to the function that implements poll() syscall
4075c7e295SMauro Carvalho Chehab  * @ioctl: pointer to the function that implements ioctl() syscall
4175c7e295SMauro Carvalho Chehab  * @compat_ioctl: pointer to the function that will handle 32 bits userspace
42*f040e0fdSRandy Dunlap  *	calls to the ioctl() syscall on a Kernel compiled with 64 bits.
4375c7e295SMauro Carvalho Chehab  * @open: pointer to the function that implements open() syscall
4475c7e295SMauro Carvalho Chehab  * @release: pointer to the function that will release the resources allocated
4575c7e295SMauro Carvalho Chehab  *	by the @open function.
4675c7e295SMauro Carvalho Chehab  */
47cf4b9211SLaurent Pinchart struct media_file_operations {
48cf4b9211SLaurent Pinchart 	struct module *owner;
49cf4b9211SLaurent Pinchart 	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
50cf4b9211SLaurent Pinchart 	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
51a3f8683bSAl Viro 	__poll_t (*poll) (struct file *, struct poll_table_struct *);
52cf4b9211SLaurent Pinchart 	long (*ioctl) (struct file *, unsigned int, unsigned long);
53c6c1d50bSSakari Ailus 	long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
54cf4b9211SLaurent Pinchart 	int (*open) (struct file *);
55cf4b9211SLaurent Pinchart 	int (*release) (struct file *);
56cf4b9211SLaurent Pinchart };
57cf4b9211SLaurent Pinchart 
58cf4b9211SLaurent Pinchart /**
59cf4b9211SLaurent Pinchart  * struct media_devnode - Media device node
600db5c799SMauro Carvalho Chehab  * @media_dev:	pointer to struct &media_device
6175c7e295SMauro Carvalho Chehab  * @fops:	pointer to struct &media_file_operations with media device ops
620db5c799SMauro Carvalho Chehab  * @dev:	pointer to struct &device containing the media controller device
63ec0255caSMauro Carvalho Chehab  * @cdev:	struct cdev pointer character device
64cf4b9211SLaurent Pinchart  * @parent:	parent device
65cf4b9211SLaurent Pinchart  * @minor:	device node minor number
6648a7c4baSMauro Carvalho Chehab  * @flags:	flags, combination of the ``MEDIA_FLAG_*`` constants
6782631b5bSMauro Carvalho Chehab  * @release:	release callback called at the end of ``media_devnode_release()``
6882631b5bSMauro Carvalho Chehab  *		routine at media-device.c.
69cf4b9211SLaurent Pinchart  *
70cf4b9211SLaurent Pinchart  * This structure represents a media-related device node.
71cf4b9211SLaurent Pinchart  *
72cf4b9211SLaurent Pinchart  * The @parent is a physical device. It must be set by core or device drivers
73cf4b9211SLaurent Pinchart  * before registering the node.
74cf4b9211SLaurent Pinchart  */
75cf4b9211SLaurent Pinchart struct media_devnode {
76a087ce70SMauro Carvalho Chehab 	struct media_device *media_dev;
77a087ce70SMauro Carvalho Chehab 
78cf4b9211SLaurent Pinchart 	/* device ops */
79cf4b9211SLaurent Pinchart 	const struct media_file_operations *fops;
80cf4b9211SLaurent Pinchart 
81cf4b9211SLaurent Pinchart 	/* sysfs */
82cf4b9211SLaurent Pinchart 	struct device dev;		/* media device */
83cf4b9211SLaurent Pinchart 	struct cdev cdev;		/* character device */
84cf4b9211SLaurent Pinchart 	struct device *parent;		/* device parent */
85cf4b9211SLaurent Pinchart 
86cf4b9211SLaurent Pinchart 	/* device info */
87cf4b9211SLaurent Pinchart 	int minor;
88cf4b9211SLaurent Pinchart 	unsigned long flags;		/* Use bitops to access flags */
89cf4b9211SLaurent Pinchart 
90cf4b9211SLaurent Pinchart 	/* callbacks */
91163f1e93SMauro Carvalho Chehab 	void (*release)(struct media_devnode *devnode);
92cf4b9211SLaurent Pinchart };
93cf4b9211SLaurent Pinchart 
94cf4b9211SLaurent Pinchart /* dev to media_devnode */
95cf4b9211SLaurent Pinchart #define to_media_devnode(cd) container_of(cd, struct media_devnode, dev)
96cf4b9211SLaurent Pinchart 
97fe3c565eSMauro Carvalho Chehab /**
98fe3c565eSMauro Carvalho Chehab  * media_devnode_register - register a media device node
99fe3c565eSMauro Carvalho Chehab  *
1000db5c799SMauro Carvalho Chehab  * @mdev: struct media_device we want to register a device node
101163f1e93SMauro Carvalho Chehab  * @devnode: media device node structure we want to register
102fe3c565eSMauro Carvalho Chehab  * @owner: should be filled with %THIS_MODULE
103fe3c565eSMauro Carvalho Chehab  *
104fe3c565eSMauro Carvalho Chehab  * The registration code assigns minor numbers and registers the new device node
105fe3c565eSMauro Carvalho Chehab  * with the kernel. An error is returned if no free minor number can be found,
106fe3c565eSMauro Carvalho Chehab  * or if the registration of the device node fails.
107fe3c565eSMauro Carvalho Chehab  *
108fe3c565eSMauro Carvalho Chehab  * Zero is returned on success.
109fe3c565eSMauro Carvalho Chehab  *
110fe3c565eSMauro Carvalho Chehab  * Note that if the media_devnode_register call fails, the release() callback of
111fe3c565eSMauro Carvalho Chehab  * the media_devnode structure is *not* called, so the caller is responsible for
112fe3c565eSMauro Carvalho Chehab  * freeing any data.
113fe3c565eSMauro Carvalho Chehab  */
114a087ce70SMauro Carvalho Chehab int __must_check media_devnode_register(struct media_device *mdev,
115a087ce70SMauro Carvalho Chehab 					struct media_devnode *devnode,
11685de721cSSakari Ailus 					struct module *owner);
117fe3c565eSMauro Carvalho Chehab 
118fe3c565eSMauro Carvalho Chehab /**
1196f0dd24aSShuah Khan  * media_devnode_unregister_prepare - clear the media device node register bit
1206f0dd24aSShuah Khan  * @devnode: the device node to prepare for unregister
1216f0dd24aSShuah Khan  *
1226f0dd24aSShuah Khan  * This clears the passed device register bit. Future open calls will be met
1236f0dd24aSShuah Khan  * with errors. Should be called before media_devnode_unregister() to avoid
1246f0dd24aSShuah Khan  * races with unregister and device file open calls.
1256f0dd24aSShuah Khan  *
1266f0dd24aSShuah Khan  * This function can safely be called if the device node has never been
1276f0dd24aSShuah Khan  * registered or has already been unregistered.
1286f0dd24aSShuah Khan  */
1296f0dd24aSShuah Khan void media_devnode_unregister_prepare(struct media_devnode *devnode);
1306f0dd24aSShuah Khan 
1316f0dd24aSShuah Khan /**
132fe3c565eSMauro Carvalho Chehab  * media_devnode_unregister - unregister a media device node
133163f1e93SMauro Carvalho Chehab  * @devnode: the device node to unregister
134fe3c565eSMauro Carvalho Chehab  *
135fe3c565eSMauro Carvalho Chehab  * This unregisters the passed device. Future open calls will be met with
136fe3c565eSMauro Carvalho Chehab  * errors.
137fe3c565eSMauro Carvalho Chehab  *
1386f0dd24aSShuah Khan  * Should be called after media_devnode_unregister_prepare()
139fe3c565eSMauro Carvalho Chehab  */
140163f1e93SMauro Carvalho Chehab void media_devnode_unregister(struct media_devnode *devnode);
141cf4b9211SLaurent Pinchart 
14275c7e295SMauro Carvalho Chehab /**
14375c7e295SMauro Carvalho Chehab  * media_devnode_data - returns a pointer to the &media_devnode
14475c7e295SMauro Carvalho Chehab  *
14575c7e295SMauro Carvalho Chehab  * @filp: pointer to struct &file
14675c7e295SMauro Carvalho Chehab  */
media_devnode_data(struct file * filp)147cf4b9211SLaurent Pinchart static inline struct media_devnode *media_devnode_data(struct file *filp)
148cf4b9211SLaurent Pinchart {
149cf4b9211SLaurent Pinchart 	return filp->private_data;
150cf4b9211SLaurent Pinchart }
151cf4b9211SLaurent Pinchart 
15275c7e295SMauro Carvalho Chehab /**
15375c7e295SMauro Carvalho Chehab  * media_devnode_is_registered - returns true if &media_devnode is registered;
15475c7e295SMauro Carvalho Chehab  *	false otherwise.
15575c7e295SMauro Carvalho Chehab  *
156163f1e93SMauro Carvalho Chehab  * @devnode: pointer to struct &media_devnode.
157a087ce70SMauro Carvalho Chehab  *
158a087ce70SMauro Carvalho Chehab  * Note: If mdev is NULL, it also returns false.
15975c7e295SMauro Carvalho Chehab  */
media_devnode_is_registered(struct media_devnode * devnode)160163f1e93SMauro Carvalho Chehab static inline int media_devnode_is_registered(struct media_devnode *devnode)
161cf4b9211SLaurent Pinchart {
162a087ce70SMauro Carvalho Chehab 	if (!devnode)
163a087ce70SMauro Carvalho Chehab 		return false;
164a087ce70SMauro Carvalho Chehab 
165163f1e93SMauro Carvalho Chehab 	return test_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
166cf4b9211SLaurent Pinchart }
167cf4b9211SLaurent Pinchart 
168cf4b9211SLaurent Pinchart #endif /* _MEDIA_DEVNODE_H */
169