mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 00:54:09 +08:00
iio: core: wrap iio device & buffer into struct for character devices
In order to keep backwards compatibility with the current chardev mechanism, and in order to add support for multiple buffers per IIO device, we need to pass both the IIO device & IIO buffer to the chardev. This is particularly needed for the iio_buffer_read_outer() function, where we need to pass another buffer object than 'indio_dev->buffer'. Since we'll also open some chardevs via anon inodes, we can pass extra buffers in that function by assigning another object to the iio_dev_buffer_pair object. Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com> Link: https://lore.kernel.org/r/20210215104043.91251-17-alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
4991f3ea2a
commit
be24dcb113
@ -18,6 +18,11 @@ struct iio_dev;
|
||||
|
||||
extern struct device_type iio_device_type;
|
||||
|
||||
struct iio_dev_buffer_pair {
|
||||
struct iio_dev *indio_dev;
|
||||
struct iio_buffer *buffer;
|
||||
};
|
||||
|
||||
#define IIO_IOCTL_UNHANDLED 1
|
||||
struct iio_ioctl_handler {
|
||||
struct list_head entry;
|
||||
|
@ -104,8 +104,9 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
|
||||
ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf,
|
||||
size_t n, loff_t *f_ps)
|
||||
{
|
||||
struct iio_dev *indio_dev = filp->private_data;
|
||||
struct iio_buffer *rb = indio_dev->buffer;
|
||||
struct iio_dev_buffer_pair *ib = filp->private_data;
|
||||
struct iio_buffer *rb = ib->buffer;
|
||||
struct iio_dev *indio_dev = ib->indio_dev;
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
size_t datum_size;
|
||||
size_t to_wait;
|
||||
@ -170,8 +171,9 @@ ssize_t iio_buffer_read_outer(struct file *filp, char __user *buf,
|
||||
__poll_t iio_buffer_poll(struct file *filp,
|
||||
struct poll_table_struct *wait)
|
||||
{
|
||||
struct iio_dev *indio_dev = filp->private_data;
|
||||
struct iio_buffer *rb = indio_dev->buffer;
|
||||
struct iio_dev_buffer_pair *ib = filp->private_data;
|
||||
struct iio_buffer *rb = ib->buffer;
|
||||
struct iio_dev *indio_dev = ib->indio_dev;
|
||||
|
||||
if (!indio_dev->info || rb == NULL)
|
||||
return 0;
|
||||
|
@ -1705,13 +1705,24 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct iio_dev *indio_dev = container_of(inode->i_cdev,
|
||||
struct iio_dev, chrdev);
|
||||
struct iio_dev_buffer_pair *ib;
|
||||
|
||||
if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags))
|
||||
return -EBUSY;
|
||||
|
||||
iio_device_get(indio_dev);
|
||||
|
||||
filp->private_data = indio_dev;
|
||||
ib = kmalloc(sizeof(*ib), GFP_KERNEL);
|
||||
if (!ib) {
|
||||
iio_device_put(indio_dev);
|
||||
clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ib->indio_dev = indio_dev;
|
||||
ib->buffer = indio_dev->buffer;
|
||||
|
||||
filp->private_data = ib;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1725,8 +1736,10 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp)
|
||||
*/
|
||||
static int iio_chrdev_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct iio_dev_buffer_pair *ib = filp->private_data;
|
||||
struct iio_dev *indio_dev = container_of(inode->i_cdev,
|
||||
struct iio_dev, chrdev);
|
||||
kfree(ib);
|
||||
clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags);
|
||||
iio_device_put(indio_dev);
|
||||
|
||||
@ -1748,7 +1761,8 @@ void iio_device_ioctl_handler_unregister(struct iio_ioctl_handler *h)
|
||||
|
||||
static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct iio_dev *indio_dev = filp->private_data;
|
||||
struct iio_dev_buffer_pair *ib = filp->private_data;
|
||||
struct iio_dev *indio_dev = ib->indio_dev;
|
||||
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
|
||||
struct iio_ioctl_handler *h;
|
||||
int ret = -ENODEV;
|
||||
|
Loading…
Reference in New Issue
Block a user