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