672 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Industrial I/O event handling3 *4 * Copyright (c) 2008 Jonathan Cameron5 *6 * Based on elements of hwmon and input subsystems.7 */8 9#include <linux/anon_inodes.h>10#include <linux/device.h>11#include <linux/fs.h>12#include <linux/kernel.h>13#include <linux/kfifo.h>14#include <linux/module.h>15#include <linux/poll.h>16#include <linux/sched.h>17#include <linux/slab.h>18#include <linux/uaccess.h>19#include <linux/wait.h>20#include <linux/iio/iio.h>21#include <linux/iio/iio-opaque.h>22#include "iio_core.h"23#include <linux/iio/sysfs.h>24#include <linux/iio/events.h>25 26/**27 * struct iio_event_interface - chrdev interface for an event line28 * @wait: wait queue to allow blocking reads of events29 * @det_events: list of detected events30 * @dev_attr_list: list of event interface sysfs attribute31 * @flags: file operations related flags including busy flag.32 * @group: event interface sysfs attribute group33 * @read_lock: lock to protect kfifo read operations34 * @ioctl_handler: handler for event ioctl() calls35 */36struct iio_event_interface {37 wait_queue_head_t wait;38 DECLARE_KFIFO(det_events, struct iio_event_data, 16);39 40 struct list_head dev_attr_list;41 unsigned long flags;42 struct attribute_group group;43 struct mutex read_lock;44 struct iio_ioctl_handler ioctl_handler;45};46 47bool iio_event_enabled(const struct iio_event_interface *ev_int)48{49 return !!test_bit(IIO_BUSY_BIT_POS, &ev_int->flags);50}51 52/**53 * iio_push_event() - try to add event to the list for userspace reading54 * @indio_dev: IIO device structure55 * @ev_code: What event56 * @timestamp: When the event occurred57 *58 * Note: The caller must make sure that this function is not running59 * concurrently for the same indio_dev more than once.60 *61 * This function may be safely used as soon as a valid reference to iio_dev has62 * been obtained via iio_device_alloc(), but any events that are submitted63 * before iio_device_register() has successfully completed will be silently64 * discarded.65 **/66int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)67{68 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);69 struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;70 struct iio_event_data ev;71 int copied;72 73 if (!ev_int)74 return 0;75 76 /* Does anyone care? */77 if (iio_event_enabled(ev_int)) {78 79 ev.id = ev_code;80 ev.timestamp = timestamp;81 82 copied = kfifo_put(&ev_int->det_events, ev);83 if (copied != 0)84 wake_up_poll(&ev_int->wait, EPOLLIN);85 }86 87 return 0;88}89EXPORT_SYMBOL(iio_push_event);90 91/**92 * iio_event_poll() - poll the event queue to find out if it has data93 * @filep: File structure pointer to identify the device94 * @wait: Poll table pointer to add the wait queue on95 *96 * Return: (EPOLLIN | EPOLLRDNORM) if data is available for reading97 * or a negative error code on failure98 */99static __poll_t iio_event_poll(struct file *filep,100 struct poll_table_struct *wait)101{102 struct iio_dev *indio_dev = filep->private_data;103 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);104 struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;105 __poll_t events = 0;106 107 if (!indio_dev->info)108 return events;109 110 poll_wait(filep, &ev_int->wait, wait);111 112 if (!kfifo_is_empty(&ev_int->det_events))113 events = EPOLLIN | EPOLLRDNORM;114 115 return events;116}117 118static ssize_t iio_event_chrdev_read(struct file *filep,119 char __user *buf,120 size_t count,121 loff_t *f_ps)122{123 struct iio_dev *indio_dev = filep->private_data;124 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);125 struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;126 unsigned int copied;127 int ret;128 129 if (!indio_dev->info)130 return -ENODEV;131 132 if (count < sizeof(struct iio_event_data))133 return -EINVAL;134 135 do {136 if (kfifo_is_empty(&ev_int->det_events)) {137 if (filep->f_flags & O_NONBLOCK)138 return -EAGAIN;139 140 ret = wait_event_interruptible(ev_int->wait,141 !kfifo_is_empty(&ev_int->det_events) ||142 indio_dev->info == NULL);143 if (ret)144 return ret;145 if (indio_dev->info == NULL)146 return -ENODEV;147 }148 149 if (mutex_lock_interruptible(&ev_int->read_lock))150 return -ERESTARTSYS;151 ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied);152 mutex_unlock(&ev_int->read_lock);153 154 if (ret)155 return ret;156 157 /*158 * If we couldn't read anything from the fifo (a different159 * thread might have been faster) we either return -EAGAIN if160 * the file descriptor is non-blocking, otherwise we go back to161 * sleep and wait for more data to arrive.162 */163 if (copied == 0 && (filep->f_flags & O_NONBLOCK))164 return -EAGAIN;165 166 } while (copied == 0);167 168 return copied;169}170 171static int iio_event_chrdev_release(struct inode *inode, struct file *filep)172{173 struct iio_dev *indio_dev = filep->private_data;174 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);175 struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;176 177 clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);178 179 iio_device_put(indio_dev);180 181 return 0;182}183 184static const struct file_operations iio_event_chrdev_fileops = {185 .read = iio_event_chrdev_read,186 .poll = iio_event_poll,187 .release = iio_event_chrdev_release,188 .owner = THIS_MODULE,189 .llseek = noop_llseek,190};191 192static int iio_event_getfd(struct iio_dev *indio_dev)193{194 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);195 struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;196 int fd;197 198 if (ev_int == NULL)199 return -ENODEV;200 201 fd = mutex_lock_interruptible(&iio_dev_opaque->mlock);202 if (fd)203 return fd;204 205 if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {206 fd = -EBUSY;207 goto unlock;208 }209 210 iio_device_get(indio_dev);211 212 fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,213 indio_dev, O_RDONLY | O_CLOEXEC);214 if (fd < 0) {215 clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);216 iio_device_put(indio_dev);217 } else {218 kfifo_reset_out(&ev_int->det_events);219 }220 221unlock:222 mutex_unlock(&iio_dev_opaque->mlock);223 return fd;224}225 226static const char * const iio_ev_type_text[] = {227 [IIO_EV_TYPE_THRESH] = "thresh",228 [IIO_EV_TYPE_MAG] = "mag",229 [IIO_EV_TYPE_ROC] = "roc",230 [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",231 [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",232 [IIO_EV_TYPE_CHANGE] = "change",233 [IIO_EV_TYPE_MAG_REFERENCED] = "mag_referenced",234 [IIO_EV_TYPE_GESTURE] = "gesture",235};236 237static const char * const iio_ev_dir_text[] = {238 [IIO_EV_DIR_EITHER] = "either",239 [IIO_EV_DIR_RISING] = "rising",240 [IIO_EV_DIR_FALLING] = "falling",241 [IIO_EV_DIR_SINGLETAP] = "singletap",242 [IIO_EV_DIR_DOUBLETAP] = "doubletap",243};244 245static const char * const iio_ev_info_text[] = {246 [IIO_EV_INFO_ENABLE] = "en",247 [IIO_EV_INFO_VALUE] = "value",248 [IIO_EV_INFO_HYSTERESIS] = "hysteresis",249 [IIO_EV_INFO_PERIOD] = "period",250 [IIO_EV_INFO_HIGH_PASS_FILTER_3DB] = "high_pass_filter_3db",251 [IIO_EV_INFO_LOW_PASS_FILTER_3DB] = "low_pass_filter_3db",252 [IIO_EV_INFO_TIMEOUT] = "timeout",253 [IIO_EV_INFO_RESET_TIMEOUT] = "reset_timeout",254 [IIO_EV_INFO_TAP2_MIN_DELAY] = "tap2_min_delay",255 [IIO_EV_INFO_RUNNING_PERIOD] = "runningperiod",256 [IIO_EV_INFO_RUNNING_COUNT] = "runningcount",257};258 259static enum iio_event_direction iio_ev_attr_dir(struct iio_dev_attr *attr)260{261 return attr->c->event_spec[attr->address & 0xffff].dir;262}263 264static enum iio_event_type iio_ev_attr_type(struct iio_dev_attr *attr)265{266 return attr->c->event_spec[attr->address & 0xffff].type;267}268 269static enum iio_event_info iio_ev_attr_info(struct iio_dev_attr *attr)270{271 return (attr->address >> 16) & 0xffff;272}273 274static ssize_t iio_ev_state_store(struct device *dev,275 struct device_attribute *attr,276 const char *buf,277 size_t len)278{279 struct iio_dev *indio_dev = dev_to_iio_dev(dev);280 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);281 int ret;282 bool val;283 284 ret = kstrtobool(buf, &val);285 if (ret < 0)286 return ret;287 288 if (!indio_dev->info->write_event_config)289 return -EINVAL;290 291 ret = indio_dev->info->write_event_config(indio_dev,292 this_attr->c, iio_ev_attr_type(this_attr),293 iio_ev_attr_dir(this_attr), val);294 295 return (ret < 0) ? ret : len;296}297 298static ssize_t iio_ev_state_show(struct device *dev,299 struct device_attribute *attr,300 char *buf)301{302 struct iio_dev *indio_dev = dev_to_iio_dev(dev);303 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);304 int val;305 306 if (!indio_dev->info->read_event_config)307 return -EINVAL;308 309 val = indio_dev->info->read_event_config(indio_dev,310 this_attr->c, iio_ev_attr_type(this_attr),311 iio_ev_attr_dir(this_attr));312 if (val < 0)313 return val;314 else315 return sysfs_emit(buf, "%d\n", val);316}317 318static ssize_t iio_ev_value_show(struct device *dev,319 struct device_attribute *attr,320 char *buf)321{322 struct iio_dev *indio_dev = dev_to_iio_dev(dev);323 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);324 int val, val2, val_arr[2];325 int ret;326 327 if (!indio_dev->info->read_event_value)328 return -EINVAL;329 330 ret = indio_dev->info->read_event_value(indio_dev,331 this_attr->c, iio_ev_attr_type(this_attr),332 iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),333 &val, &val2);334 if (ret < 0)335 return ret;336 val_arr[0] = val;337 val_arr[1] = val2;338 return iio_format_value(buf, ret, 2, val_arr);339}340 341static ssize_t iio_ev_value_store(struct device *dev,342 struct device_attribute *attr,343 const char *buf,344 size_t len)345{346 struct iio_dev *indio_dev = dev_to_iio_dev(dev);347 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);348 int val, val2;349 int ret;350 351 if (!indio_dev->info->write_event_value)352 return -EINVAL;353 354 ret = iio_str_to_fixpoint(buf, 100000, &val, &val2);355 if (ret)356 return ret;357 ret = indio_dev->info->write_event_value(indio_dev,358 this_attr->c, iio_ev_attr_type(this_attr),359 iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),360 val, val2);361 if (ret < 0)362 return ret;363 364 return len;365}366 367static ssize_t iio_ev_label_show(struct device *dev,368 struct device_attribute *attr,369 char *buf)370{371 struct iio_dev *indio_dev = dev_to_iio_dev(dev);372 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);373 374 if (indio_dev->info->read_event_label)375 return indio_dev->info->read_event_label(indio_dev,376 this_attr->c, iio_ev_attr_type(this_attr),377 iio_ev_attr_dir(this_attr), buf);378 379 return -EINVAL;380}381 382static int iio_device_add_event(struct iio_dev *indio_dev,383 const struct iio_chan_spec *chan, unsigned int spec_index,384 enum iio_event_type type, enum iio_event_direction dir,385 enum iio_shared_by shared_by, const unsigned long *mask)386{387 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);388 ssize_t (*show)(struct device *dev, struct device_attribute *attr,389 char *buf);390 ssize_t (*store)(struct device *dev, struct device_attribute *attr,391 const char *buf, size_t len);392 unsigned int attrcount = 0;393 unsigned int i;394 char *postfix;395 int ret;396 397 for_each_set_bit(i, mask, sizeof(*mask)*8) {398 if (i >= ARRAY_SIZE(iio_ev_info_text))399 return -EINVAL;400 if (dir != IIO_EV_DIR_NONE)401 postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",402 iio_ev_type_text[type],403 iio_ev_dir_text[dir],404 iio_ev_info_text[i]);405 else406 postfix = kasprintf(GFP_KERNEL, "%s_%s",407 iio_ev_type_text[type],408 iio_ev_info_text[i]);409 if (postfix == NULL)410 return -ENOMEM;411 412 if (i == IIO_EV_INFO_ENABLE) {413 show = iio_ev_state_show;414 store = iio_ev_state_store;415 } else {416 show = iio_ev_value_show;417 store = iio_ev_value_store;418 }419 420 ret = __iio_add_chan_devattr(postfix, chan, show, store,421 (i << 16) | spec_index, shared_by, &indio_dev->dev,422 NULL,423 &iio_dev_opaque->event_interface->dev_attr_list);424 kfree(postfix);425 426 if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))427 continue;428 429 if (ret)430 return ret;431 432 attrcount++;433 }434 435 return attrcount;436}437 438static int iio_device_add_event_label(struct iio_dev *indio_dev,439 const struct iio_chan_spec *chan,440 unsigned int spec_index,441 enum iio_event_type type,442 enum iio_event_direction dir)443{444 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);445 char *postfix;446 int ret;447 448 if (!indio_dev->info->read_event_label)449 return 0;450 451 if (dir != IIO_EV_DIR_NONE)452 postfix = kasprintf(GFP_KERNEL, "%s_%s_label",453 iio_ev_type_text[type],454 iio_ev_dir_text[dir]);455 else456 postfix = kasprintf(GFP_KERNEL, "%s_label",457 iio_ev_type_text[type]);458 if (postfix == NULL)459 return -ENOMEM;460 461 ret = __iio_add_chan_devattr(postfix, chan, &iio_ev_label_show, NULL,462 spec_index, IIO_SEPARATE, &indio_dev->dev, NULL,463 &iio_dev_opaque->event_interface->dev_attr_list);464 465 kfree(postfix);466 467 if (ret < 0)468 return ret;469 470 return 1;471}472 473static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,474 struct iio_chan_spec const *chan)475{476 int ret = 0, i, attrcount = 0;477 enum iio_event_direction dir;478 enum iio_event_type type;479 480 for (i = 0; i < chan->num_event_specs; i++) {481 type = chan->event_spec[i].type;482 dir = chan->event_spec[i].dir;483 484 ret = iio_device_add_event(indio_dev, chan, i, type, dir,485 IIO_SEPARATE, &chan->event_spec[i].mask_separate);486 if (ret < 0)487 return ret;488 attrcount += ret;489 490 ret = iio_device_add_event(indio_dev, chan, i, type, dir,491 IIO_SHARED_BY_TYPE,492 &chan->event_spec[i].mask_shared_by_type);493 if (ret < 0)494 return ret;495 attrcount += ret;496 497 ret = iio_device_add_event(indio_dev, chan, i, type, dir,498 IIO_SHARED_BY_DIR,499 &chan->event_spec[i].mask_shared_by_dir);500 if (ret < 0)501 return ret;502 attrcount += ret;503 504 ret = iio_device_add_event(indio_dev, chan, i, type, dir,505 IIO_SHARED_BY_ALL,506 &chan->event_spec[i].mask_shared_by_all);507 if (ret < 0)508 return ret;509 attrcount += ret;510 511 ret = iio_device_add_event_label(indio_dev, chan, i, type, dir);512 if (ret < 0)513 return ret;514 attrcount += ret;515 }516 ret = attrcount;517 return ret;518}519 520static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)521{522 int j, ret, attrcount = 0;523 524 /* Dynamically created from the channels array */525 for (j = 0; j < indio_dev->num_channels; j++) {526 ret = iio_device_add_event_sysfs(indio_dev,527 &indio_dev->channels[j]);528 if (ret < 0)529 return ret;530 attrcount += ret;531 }532 return attrcount;533}534 535static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)536{537 int j;538 539 for (j = 0; j < indio_dev->num_channels; j++) {540 if (indio_dev->channels[j].num_event_specs != 0)541 return true;542 }543 return false;544}545 546static void iio_setup_ev_int(struct iio_event_interface *ev_int)547{548 INIT_KFIFO(ev_int->det_events);549 init_waitqueue_head(&ev_int->wait);550 mutex_init(&ev_int->read_lock);551}552 553static long iio_event_ioctl(struct iio_dev *indio_dev, struct file *filp,554 unsigned int cmd, unsigned long arg)555{556 int __user *ip = (int __user *)arg;557 int fd;558 559 if (cmd == IIO_GET_EVENT_FD_IOCTL) {560 fd = iio_event_getfd(indio_dev);561 if (fd < 0)562 return fd;563 if (copy_to_user(ip, &fd, sizeof(fd)))564 return -EFAULT;565 return 0;566 }567 568 return IIO_IOCTL_UNHANDLED;569}570 571static const char *iio_event_group_name = "events";572int iio_device_register_eventset(struct iio_dev *indio_dev)573{574 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);575 struct iio_event_interface *ev_int;576 struct iio_dev_attr *p;577 int ret = 0, attrcount_orig = 0, attrcount, attrn;578 struct attribute **attr;579 580 if (!(indio_dev->info->event_attrs ||581 iio_check_for_dynamic_events(indio_dev)))582 return 0;583 584 ev_int = kzalloc(sizeof(*ev_int), GFP_KERNEL);585 if (!ev_int)586 return -ENOMEM;587 588 iio_dev_opaque->event_interface = ev_int;589 590 INIT_LIST_HEAD(&ev_int->dev_attr_list);591 592 iio_setup_ev_int(ev_int);593 if (indio_dev->info->event_attrs != NULL) {594 attr = indio_dev->info->event_attrs->attrs;595 while (*attr++ != NULL)596 attrcount_orig++;597 }598 attrcount = attrcount_orig;599 if (indio_dev->channels) {600 ret = __iio_add_event_config_attrs(indio_dev);601 if (ret < 0)602 goto error_free_setup_event_lines;603 attrcount += ret;604 }605 606 ev_int->group.name = iio_event_group_name;607 ev_int->group.attrs = kcalloc(attrcount + 1,608 sizeof(ev_int->group.attrs[0]),609 GFP_KERNEL);610 if (ev_int->group.attrs == NULL) {611 ret = -ENOMEM;612 goto error_free_setup_event_lines;613 }614 if (indio_dev->info->event_attrs)615 memcpy(ev_int->group.attrs,616 indio_dev->info->event_attrs->attrs,617 sizeof(ev_int->group.attrs[0]) * attrcount_orig);618 attrn = attrcount_orig;619 /* Add all elements from the list. */620 list_for_each_entry(p, &ev_int->dev_attr_list, l)621 ev_int->group.attrs[attrn++] = &p->dev_attr.attr;622 623 ret = iio_device_register_sysfs_group(indio_dev, &ev_int->group);624 if (ret)625 goto error_free_group_attrs;626 627 ev_int->ioctl_handler.ioctl = iio_event_ioctl;628 iio_device_ioctl_handler_register(&iio_dev_opaque->indio_dev,629 &ev_int->ioctl_handler);630 631 return 0;632 633error_free_group_attrs:634 kfree(ev_int->group.attrs);635error_free_setup_event_lines:636 iio_free_chan_devattr_list(&ev_int->dev_attr_list);637 kfree(ev_int);638 iio_dev_opaque->event_interface = NULL;639 return ret;640}641 642/**643 * iio_device_wakeup_eventset - Wakes up the event waitqueue644 * @indio_dev: The IIO device645 *646 * Wakes up the event waitqueue used for poll() and blocking read().647 * Should usually be called when the device is unregistered.648 */649void iio_device_wakeup_eventset(struct iio_dev *indio_dev)650{651 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);652 653 if (iio_dev_opaque->event_interface == NULL)654 return;655 wake_up(&iio_dev_opaque->event_interface->wait);656}657 658void iio_device_unregister_eventset(struct iio_dev *indio_dev)659{660 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);661 struct iio_event_interface *ev_int = iio_dev_opaque->event_interface;662 663 if (ev_int == NULL)664 return;665 666 iio_device_ioctl_handler_unregister(&ev_int->ioctl_handler);667 iio_free_chan_devattr_list(&ev_int->dev_attr_list);668 kfree(ev_int->group.attrs);669 kfree(ev_int);670 iio_dev_opaque->event_interface = NULL;671}672