diff options
| author | Donggeun Yoo <donggeunyoo.kernel@gmail.com> | 2026-09-02 00:21:26 +0900 |
|---|---|---|
| committer | Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> | 2026-09-07 02:24:53 +0100 |
| commit | e24328974a88aa8541e94e8bb8dfa2ade1b3c45d (patch) | |
| tree | 43a2533acc955d11f5cb8be1ecba0ab8ba4cbb1e /include/media/media-devnode.h | |
| download | linux-stable-e24328974a88aa8541e94e8bb8dfa2ade1b3c45d.tar.gz linux-stable-e24328974a88aa8541e94e8bb8dfa2ade1b3c45d.zip | |
iio: proximity: vl53l0x-i2c: claim direct mode for raw readsgrafted
vl53l0x_read_raw() starts a single-shot ranging measurement and reads
back the result. Once the triggered buffer is enabled the sensor runs in
continuous mode and its data-ready interrupt is routed to the trigger,
so a concurrent in_distance_raw read disturbs the streaming setup and
never gets its completion, returning -ETIMEDOUT.
The original submission claimed direct mode here, but it was dropped
during review because the driver had no buffer support at the time [1].
Continuous (buffered) mode was later added without restoring the
claim [2], reintroducing the conflict.
Reject direct reads while buffered capture is active by claiming direct
mode around the measurement, as the vl53l1x sibling already does.
Fixes: 762186c6e7b1 ("iio: proximity: vl53l0x-i2c: Added continuous mode support")
Link: https://lore.kernel.org/linux-iio/20180911160300.GA9212@himanshu-Vostro-3559/ [1]
Link: https://lore.kernel.org/linux-iio/20240909101508.263085-3-abhashkumarjha123@gmail.com/ [2]
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Diffstat (limited to 'include/media/media-devnode.h')
| -rw-r--r-- | include/media/media-devnode.h | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h new file mode 100644 index 000000000..dbcabeffc --- /dev/null +++ b/include/media/media-devnode.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Media device node + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> + * Sakari Ailus <sakari.ailus@iki.fi> + * + * -- + * + * Common functions for media-related drivers to register and unregister media + * device nodes. + */ + +#ifndef _MEDIA_DEVNODE_H +#define _MEDIA_DEVNODE_H + +#include <linux/poll.h> +#include <linux/fs.h> +#include <linux/device.h> +#include <linux/cdev.h> +#include <linux/debugfs.h> + +struct media_device; + +/* debugfs top-level media directory */ +extern struct dentry *media_debugfs_root; + +/* + * Flag to mark the media_devnode struct as registered. Drivers must not touch + * this flag directly, it will be set and cleared by media_devnode_register and + * media_devnode_unregister. + */ +#define MEDIA_FLAG_REGISTERED 0 + +/** + * struct media_file_operations - Media device file operations + * + * @owner: should be filled with %THIS_MODULE + * @read: pointer to the function that implements read() syscall + * @write: pointer to the function that implements write() syscall + * @poll: pointer to the function that implements poll() syscall + * @ioctl: pointer to the function that implements ioctl() syscall + * @compat_ioctl: pointer to the function that will handle 32 bits userspace + * calls to the ioctl() syscall on a Kernel compiled with 64 bits. + * @open: pointer to the function that implements open() syscall + * @release: pointer to the function that will release the resources allocated + * by the @open function. + */ +struct media_file_operations { + struct module *owner; + ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); + ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); + __poll_t (*poll) (struct file *, struct poll_table_struct *); + long (*ioctl) (struct file *, unsigned int, unsigned long); + long (*compat_ioctl) (struct file *, unsigned int, unsigned long); + int (*open) (struct file *); + int (*release) (struct file *); +}; + +/** + * struct media_devnode - Media device node + * @media_dev: pointer to struct &media_device + * @fops: pointer to struct &media_file_operations with media device ops + * @dev: pointer to struct &device containing the media controller device + * @cdev: struct cdev pointer character device + * @parent: parent device + * @minor: device node minor number + * @flags: flags, combination of the ``MEDIA_FLAG_*`` constants + * @release: release callback called at the end of ``media_devnode_release()`` + * routine at media-device.c. + * + * This structure represents a media-related device node. + * + * The @parent is a physical device. It must be set by core or device drivers + * before registering the node. + */ +struct media_devnode { + struct media_device *media_dev; + + /* device ops */ + const struct media_file_operations *fops; + + /* sysfs */ + struct device dev; /* media device */ + struct cdev cdev; /* character device */ + struct device *parent; /* device parent */ + + /* device info */ + int minor; + unsigned long flags; /* Use bitops to access flags */ + + /* callbacks */ + void (*release)(struct media_devnode *devnode); +}; + +/* dev to media_devnode */ +#define to_media_devnode(cd) container_of(cd, struct media_devnode, dev) + +/** + * media_devnode_register - register a media device node + * + * @mdev: struct media_device we want to register a device node + * @devnode: media device node structure we want to register + * @owner: should be filled with %THIS_MODULE + * + * The registration code assigns minor numbers and registers the new device node + * with the kernel. An error is returned if no free minor number can be found, + * or if the registration of the device node fails. + * + * Zero is returned on success. + * + * Note that if the media_devnode_register call fails, the release() callback of + * the media_devnode structure is *not* called, so the caller is responsible for + * freeing any data. + */ +int __must_check media_devnode_register(struct media_device *mdev, + struct media_devnode *devnode, + struct module *owner); + +/** + * media_devnode_unregister_prepare - clear the media device node register bit + * @devnode: the device node to prepare for unregister + * + * This clears the passed device register bit. Future open calls will be met + * with errors. Should be called before media_devnode_unregister() to avoid + * races with unregister and device file open calls. + * + * This function can safely be called if the device node has never been + * registered or has already been unregistered. + */ +void media_devnode_unregister_prepare(struct media_devnode *devnode); + +/** + * media_devnode_unregister - unregister a media device node + * @devnode: the device node to unregister + * + * This unregisters the passed device. Future open calls will be met with + * errors. + * + * Should be called after media_devnode_unregister_prepare() + */ +void media_devnode_unregister(struct media_devnode *devnode); + +/** + * media_devnode_data - returns a pointer to the &media_devnode + * + * @filp: pointer to struct &file + */ +static inline struct media_devnode *media_devnode_data(struct file *filp) +{ + return filp->private_data; +} + +/** + * media_devnode_is_registered - returns true if &media_devnode is registered; + * false otherwise. + * + * @devnode: pointer to struct &media_devnode. + * + * Note: If mdev is NULL, it also returns false. + */ +static inline int media_devnode_is_registered(struct media_devnode *devnode) +{ + if (!devnode) + return false; + + return test_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); +} + +#endif /* _MEDIA_DEVNODE_H */ |
