diff options
Diffstat (limited to 'drivers/staging/iio/industrialio-core.c')
-rw-r--r-- | drivers/staging/iio/industrialio-core.c | 113 |
1 files changed, 38 insertions, 75 deletions
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 01030684ef28..f3bf111f354f 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -29,14 +29,11 @@ #define IIO_ID_FORMAT IIO_ID_PREFIX "%d" /* IDR to assign each registered device a unique id*/ -static DEFINE_IDR(iio_idr); - -/* IDR for general event identifiers */ -static DEFINE_IDR(iio_event_idr); +static DEFINE_IDA(iio_ida); /* IDR to allocate character device minor numbers */ -static DEFINE_IDR(iio_chrdev_idr); +static DEFINE_IDA(iio_chrdev_ida); /* Lock used to protect both of the above */ -static DEFINE_SPINLOCK(iio_idr_lock); +static DEFINE_SPINLOCK(iio_ida_lock); dev_t iio_devt; EXPORT_SYMBOL(iio_devt); @@ -62,7 +59,7 @@ EXPORT_SYMBOL(__iio_change_event); * are queued. Hence a client MUST open the chrdev before the ring buffer is * switched on. */ - int __iio_push_event(struct iio_event_interface *ev_int, +int __iio_push_event(struct iio_event_interface *ev_int, int ev_code, s64 timestamp, struct iio_shared_ev_pointer * @@ -128,19 +125,10 @@ static irqreturn_t iio_interrupt_handler(int irq, void *_int_info) } time_ns = iio_get_time_ns(); - /* detect single element list*/ - if (list_is_singular(&int_info->ev_list)) { + list_for_each_entry(p, &int_info->ev_list, list) { disable_irq_nosync(irq); - p = list_first_entry(&int_info->ev_list, - struct iio_event_handler_list, - list); - /* single event handler - maybe shared */ p->handler(dev_info, 1, time_ns, !(p->refcount > 1)); - } else - list_for_each_entry(p, &int_info->ev_list, list) { - disable_irq_nosync(irq); - p->handler(dev_info, 1, time_ns, 0); - } + } spin_unlock_irqrestore(&int_info->ev_list_lock, flags); return IRQ_HANDLED; @@ -352,6 +340,7 @@ static const struct file_operations iio_event_chrdev_fileops = { .release = iio_event_chrdev_release, .open = iio_event_chrdev_open, .owner = THIS_MODULE, + .llseek = noop_llseek, }; static void iio_event_dev_release(struct device *dev) @@ -370,14 +359,14 @@ int iio_device_get_chrdev_minor(void) { int ret, val; -idr_again: - if (unlikely(idr_pre_get(&iio_chrdev_idr, GFP_KERNEL) == 0)) +ida_again: + if (unlikely(ida_pre_get(&iio_chrdev_ida, GFP_KERNEL) == 0)) return -ENOMEM; - spin_lock(&iio_idr_lock); - ret = idr_get_new(&iio_chrdev_idr, NULL, &val); - spin_unlock(&iio_idr_lock); + spin_lock(&iio_ida_lock); + ret = ida_get_new(&iio_chrdev_ida, &val); + spin_unlock(&iio_ida_lock); if (unlikely(ret == -EAGAIN)) - goto idr_again; + goto ida_again; else if (unlikely(ret)) return ret; if (val > IIO_DEV_MAX) @@ -387,9 +376,9 @@ idr_again: void iio_device_free_chrdev_minor(int val) { - spin_lock(&iio_idr_lock); - idr_remove(&iio_chrdev_idr, val); - spin_unlock(&iio_idr_lock); + spin_lock(&iio_ida_lock); + ida_remove(&iio_chrdev_ida, val); + spin_unlock(&iio_ida_lock); } int iio_setup_ev_int(struct iio_event_interface *ev_int, @@ -510,62 +499,49 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info) goto error_ret; } - if (dev_info->scan_el_attrs) { - ret = sysfs_create_group(&dev_info->dev.kobj, - dev_info->scan_el_attrs); - if (ret) - dev_err(&dev_info->dev, - "Failed to add sysfs scan els\n"); - } - error_ret: return ret; } static void iio_device_unregister_sysfs(struct iio_dev *dev_info) { - if (dev_info->scan_el_attrs) - sysfs_remove_group(&dev_info->dev.kobj, - dev_info->scan_el_attrs); - sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs); } /* Return a negative errno on failure */ -int iio_get_new_idr_val(struct idr *this_idr) +int iio_get_new_ida_val(struct ida *this_ida) { int ret; int val; -idr_again: - if (unlikely(idr_pre_get(this_idr, GFP_KERNEL) == 0)) +ida_again: + if (unlikely(ida_pre_get(this_ida, GFP_KERNEL) == 0)) return -ENOMEM; - spin_lock(&iio_idr_lock); - ret = idr_get_new(this_idr, NULL, &val); - spin_unlock(&iio_idr_lock); + spin_lock(&iio_ida_lock); + ret = ida_get_new(this_ida, &val); + spin_unlock(&iio_ida_lock); if (unlikely(ret == -EAGAIN)) - goto idr_again; + goto ida_again; else if (unlikely(ret)) return ret; return val; } -EXPORT_SYMBOL(iio_get_new_idr_val); +EXPORT_SYMBOL(iio_get_new_ida_val); -void iio_free_idr_val(struct idr *this_idr, int id) +void iio_free_ida_val(struct ida *this_ida, int id) { - spin_lock(&iio_idr_lock); - idr_remove(this_idr, id); - spin_unlock(&iio_idr_lock); + spin_lock(&iio_ida_lock); + ida_remove(this_ida, id); + spin_unlock(&iio_ida_lock); } -EXPORT_SYMBOL(iio_free_idr_val); +EXPORT_SYMBOL(iio_free_ida_val); static int iio_device_register_id(struct iio_dev *dev_info, - struct idr *this_idr) + struct ida *this_ida) { - - dev_info->id = iio_get_new_idr_val(&iio_idr); + dev_info->id = iio_get_new_ida_val(&iio_ida); if (dev_info->id < 0) return dev_info->id; return 0; @@ -573,7 +549,7 @@ static int iio_device_register_id(struct iio_dev *dev_info, static void iio_device_unregister_id(struct iio_dev *dev_info) { - iio_free_idr_val(&iio_idr, dev_info->id); + iio_free_ida_val(&iio_ida, dev_info->id); } static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i) @@ -654,16 +630,11 @@ static int iio_device_register_eventset(struct iio_dev *dev_info) for (i = 0; i < dev_info->num_interrupt_lines; i++) { dev_info->event_interfaces[i].owner = dev_info->driver_module; - ret = iio_get_new_idr_val(&iio_event_idr); - if (ret < 0) - goto error_free_setup_ev_ints; - else - dev_info->event_interfaces[i].id = ret; snprintf(dev_info->event_interfaces[i]._name, 20, "%s:event%d", dev_name(&dev_info->dev), - dev_info->event_interfaces[i].id); + i); ret = iio_setup_ev_int(&dev_info->event_interfaces[i], (const char *)(dev_info @@ -674,8 +645,6 @@ static int iio_device_register_eventset(struct iio_dev *dev_info) if (ret) { dev_err(&dev_info->dev, "Could not get chrdev interface\n"); - iio_free_idr_val(&iio_event_idr, - dev_info->event_interfaces[i].id); goto error_free_setup_ev_ints; } @@ -711,11 +680,8 @@ error_remove_sysfs_interfaces: ->event_interfaces[j].dev.kobj, &dev_info->event_attrs[j]); error_free_setup_ev_ints: - for (j = 0; j < i; j++) { - iio_free_idr_val(&iio_event_idr, - dev_info->event_interfaces[j].id); + for (j = 0; j < i; j++) iio_free_ev_int(&dev_info->event_interfaces[j]); - } kfree(dev_info->interrupts); error_free_event_interfaces: kfree(dev_info->event_interfaces); @@ -735,11 +701,8 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info) ->event_interfaces[i].dev.kobj, &dev_info->event_attrs[i]); - for (i = 0; i < dev_info->num_interrupt_lines; i++) { - iio_free_idr_val(&iio_event_idr, - dev_info->event_interfaces[i].id); + for (i = 0; i < dev_info->num_interrupt_lines; i++) iio_free_ev_int(&dev_info->event_interfaces[i]); - } kfree(dev_info->interrupts); kfree(dev_info->event_interfaces); } @@ -785,7 +748,7 @@ int iio_device_register(struct iio_dev *dev_info) { int ret; - ret = iio_device_register_id(dev_info, &iio_idr); + ret = iio_device_register_id(dev_info, &iio_ida); if (ret) { dev_err(&dev_info->dev, "Failed to get id\n"); goto error_ret; @@ -794,7 +757,7 @@ int iio_device_register(struct iio_dev *dev_info) ret = device_add(&dev_info->dev); if (ret) - goto error_free_idr; + goto error_free_ida; ret = iio_device_register_sysfs(dev_info); if (ret) { dev_err(dev_info->dev.parent, @@ -816,7 +779,7 @@ error_free_sysfs: iio_device_unregister_sysfs(dev_info); error_del_device: device_del(&dev_info->dev); -error_free_idr: +error_free_ida: iio_device_unregister_id(dev_info); error_ret: return ret; |