diff options
author | Alexandru Ardelean <alexandru.ardelean@analog.com> | 2020-09-24 10:41:55 +0200 |
---|---|---|
committer | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2020-11-14 16:31:25 +0100 |
commit | 8dedcc3eee3aceb37832176f0a1b03d5687acda3 (patch) | |
tree | 1364f8a7dc31966f1e9a9d575a2ee69a65e19f41 /drivers/iio/industrialio-event.c | |
parent | iio: adc: mt6360: Add ADC driver for MT6360 (diff) | |
download | linux-8dedcc3eee3aceb37832176f0a1b03d5687acda3.tar.xz linux-8dedcc3eee3aceb37832176f0a1b03d5687acda3.zip |
iio: core: centralize ioctl() calls to the main chardev
The aim of this is to improve a bit the organization of ioctl() calls in
IIO core. Currently the chardev is split across IIO core sub-modules/files.
The main chardev has to be able to handle ioctl() calls, and if we need to
add buffer ioctl() calls, this would complicate things.
The 'industrialio-core.c' file will provide a 'iio_device_ioctl()' which
will iterate over a list of ioctls registered with the IIO device. These
can be event ioctl() or buffer ioctl() calls, or something else.
Each ioctl() handler will have to return a IIO_IOCTL_UNHANDLED code (which
is positive 1), if the ioctl() did not handle the call in any. This
eliminates any potential ambiguities about negative error codes, which
should fail the call altogether.
If any ioctl() returns 0, it was considered that it was serviced
successfully and the loop will exit.
This change also moves the handling of the IIO_GET_EVENT_FD_IOCTL command
inside 'industrialio-event.c', where this is better suited.
This patch is a combination of 2 other patches from an older series:
Patch 1: iio: core: add simple centralized mechanism for ioctl() handlers
Link: https://lore.kernel.org/linux-iio/20200427131100.50845-6-alexandru.ardelean@analog.com/
Patch 2: iio: core: use new common ioctl() mechanism
Link: https://lore.kernel.org/linux-iio/20200427131100.50845-7-alexandru.ardelean@analog.com/
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20200924084155.99406-1-alexandru.ardelean@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio/industrialio-event.c')
-rw-r--r-- | drivers/iio/industrialio-event.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 99ba657b8568..7e532117ac55 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -31,6 +31,7 @@ * @flags: file operations related flags including busy flag. * @group: event interface sysfs attribute group * @read_lock: lock to protect kfifo read operations + * @ioctl_handler: handler for event ioctl() calls */ struct iio_event_interface { wait_queue_head_t wait; @@ -40,6 +41,7 @@ struct iio_event_interface { unsigned long flags; struct attribute_group group; struct mutex read_lock; + struct iio_ioctl_handler ioctl_handler; }; bool iio_event_enabled(const struct iio_event_interface *ev_int) @@ -187,7 +189,7 @@ static const struct file_operations iio_event_chrdev_fileops = { .llseek = noop_llseek, }; -int iio_event_getfd(struct iio_dev *indio_dev) +static int iio_event_getfd(struct iio_dev *indio_dev) { struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); struct iio_event_interface *ev_int = iio_dev_opaque->event_interface; @@ -473,6 +475,24 @@ static void iio_setup_ev_int(struct iio_event_interface *ev_int) mutex_init(&ev_int->read_lock); } +static long iio_event_ioctl(struct iio_dev *indio_dev, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int __user *ip = (int __user *)arg; + int fd; + + if (cmd == IIO_GET_EVENT_FD_IOCTL) { + fd = iio_event_getfd(indio_dev); + if (fd < 0) + return fd; + if (copy_to_user(ip, &fd, sizeof(fd))) + return -EFAULT; + return 0; + } + + return IIO_IOCTL_UNHANDLED; +} + static const char *iio_event_group_name = "events"; int iio_device_register_eventset(struct iio_dev *indio_dev) { @@ -526,6 +546,10 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) ev_int->group.attrs[attrn++] = &p->dev_attr.attr; indio_dev->groups[indio_dev->groupcounter++] = &ev_int->group; + ev_int->ioctl_handler.ioctl = iio_event_ioctl; + iio_device_ioctl_handler_register(&iio_dev_opaque->indio_dev, + &ev_int->ioctl_handler); + return 0; error_free_setup_event_lines: @@ -558,6 +582,8 @@ void iio_device_unregister_eventset(struct iio_dev *indio_dev) if (ev_int == NULL) return; + + iio_device_ioctl_handler_unregister(&ev_int->ioctl_handler); iio_free_chan_devattr_list(&ev_int->dev_attr_list); kfree(ev_int->group.attrs); kfree(ev_int); |