Commit be24dcb1 authored by Alexandru Ardelean's avatar Alexandru Ardelean Committed by Jonathan Cameron

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: default avatarAlexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20210215104043.91251-17-alexandru.ardelean@analog.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 4991f3ea
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment