On 04/14/2013 12:54 PM, Jonathan Cameron wrote: > This simple driver is rather useful. No issues about its interface > have been raised for some time hence the proposal to move it out > of staging. > > Signed-off-by: Jonathan Cameron <jic23@xxxxxxxxxx> Applied to the togreg branch of iio.git > --- > drivers/iio/Kconfig | 3 + > drivers/iio/Makefile | 1 + > drivers/iio/trigger/Kconfig | 17 ++ > drivers/iio/trigger/Makefile | 5 + > drivers/iio/trigger/iio-trig-sysfs.c | 227 +++++++++++++++++++++++++++ > drivers/staging/iio/trigger/Kconfig | 11 -- > drivers/staging/iio/trigger/Makefile | 1 - > drivers/staging/iio/trigger/iio-trig-sysfs.c | 227 --------------------------- > 8 files changed, 253 insertions(+), 239 deletions(-) > > diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig > index b2f963b..daa3ddd 100644 > --- a/drivers/iio/Kconfig > +++ b/drivers/iio/Kconfig > @@ -70,5 +70,8 @@ source "drivers/iio/gyro/Kconfig" > source "drivers/iio/imu/Kconfig" > source "drivers/iio/light/Kconfig" > source "drivers/iio/magnetometer/Kconfig" > +if IIO_TRIGGER > + source "drivers/iio/trigger/Kconfig" > +endif #IIO_TRIGGER > > endif # IIO > diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile > index a0e8cdd..a349a96 100644 > --- a/drivers/iio/Makefile > +++ b/drivers/iio/Makefile > @@ -21,3 +21,4 @@ obj-y += frequency/ > obj-y += imu/ > obj-y += light/ > obj-y += magnetometer/ > +obj-y += trigger/ > diff --git a/drivers/iio/trigger/Kconfig b/drivers/iio/trigger/Kconfig > new file mode 100644 > index 0000000..a4e68db > --- /dev/null > +++ b/drivers/iio/trigger/Kconfig > @@ -0,0 +1,17 @@ > +# > +# Industrial I/O standalone triggers > +# > +menu "Triggers - standalone" > + > +config IIO_SYSFS_TRIGGER > + tristate "SYSFS trigger" > + depends on SYSFS > + select IRQ_WORK > + help > + Provides support for using SYSFS entry as IIO triggers. > + If unsure, say N (but it's safe to say "Y"). > + > + To compile this driver as a module, choose M here: the > + module will be called iio-trig-sysfs. > + > +endmenu > diff --git a/drivers/iio/trigger/Makefile b/drivers/iio/trigger/Makefile > new file mode 100644 > index 0000000..e0b2183 > --- /dev/null > +++ b/drivers/iio/trigger/Makefile > @@ -0,0 +1,5 @@ > +# > +# Makefile for triggers not associated with iio-devices > +# > + > +obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o > diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c > new file mode 100644 > index 0000000..b727bde > --- /dev/null > +++ b/drivers/iio/trigger/iio-trig-sysfs.c > @@ -0,0 +1,227 @@ > +/* > + * Copyright 2011 Analog Devices Inc. > + * > + * Licensed under the GPL-2. > + * > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/platform_device.h> > +#include <linux/slab.h> > +#include <linux/list.h> > +#include <linux/irq_work.h> > + > +#include <linux/iio/iio.h> > +#include <linux/iio/trigger.h> > + > +struct iio_sysfs_trig { > + struct iio_trigger *trig; > + struct irq_work work; > + int id; > + struct list_head l; > +}; > + > +static LIST_HEAD(iio_sysfs_trig_list); > +static DEFINE_MUTEX(iio_syfs_trig_list_mut); > + > +static int iio_sysfs_trigger_probe(int id); > +static ssize_t iio_sysfs_trig_add(struct device *dev, > + struct device_attribute *attr, > + const char *buf, > + size_t len) > +{ > + int ret; > + unsigned long input; > + > + ret = strict_strtoul(buf, 10, &input); > + if (ret) > + return ret; > + ret = iio_sysfs_trigger_probe(input); > + if (ret) > + return ret; > + return len; > +} > +static DEVICE_ATTR(add_trigger, S_IWUSR, NULL, &iio_sysfs_trig_add); > + > +static int iio_sysfs_trigger_remove(int id); > +static ssize_t iio_sysfs_trig_remove(struct device *dev, > + struct device_attribute *attr, > + const char *buf, > + size_t len) > +{ > + int ret; > + unsigned long input; > + > + ret = strict_strtoul(buf, 10, &input); > + if (ret) > + return ret; > + ret = iio_sysfs_trigger_remove(input); > + if (ret) > + return ret; > + return len; > +} > + > +static DEVICE_ATTR(remove_trigger, S_IWUSR, NULL, &iio_sysfs_trig_remove); > + > +static struct attribute *iio_sysfs_trig_attrs[] = { > + &dev_attr_add_trigger.attr, > + &dev_attr_remove_trigger.attr, > + NULL, > +}; > + > +static const struct attribute_group iio_sysfs_trig_group = { > + .attrs = iio_sysfs_trig_attrs, > +}; > + > +static const struct attribute_group *iio_sysfs_trig_groups[] = { > + &iio_sysfs_trig_group, > + NULL > +}; > + > + > +/* Nothing to actually do upon release */ > +static void iio_trigger_sysfs_release(struct device *dev) > +{ > +} > + > +static struct device iio_sysfs_trig_dev = { > + .bus = &iio_bus_type, > + .groups = iio_sysfs_trig_groups, > + .release = &iio_trigger_sysfs_release, > +}; > + > +static void iio_sysfs_trigger_work(struct irq_work *work) > +{ > + struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig, > + work); > + > + iio_trigger_poll(trig->trig, 0); > +} > + > +static ssize_t iio_sysfs_trigger_poll(struct device *dev, > + struct device_attribute *attr, const char *buf, size_t count) > +{ > + struct iio_trigger *trig = to_iio_trigger(dev); > + struct iio_sysfs_trig *sysfs_trig = iio_trigger_get_drvdata(trig); > + > + irq_work_queue(&sysfs_trig->work); > + > + return count; > +} > + > +static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll); > + > +static struct attribute *iio_sysfs_trigger_attrs[] = { > + &dev_attr_trigger_now.attr, > + NULL, > +}; > + > +static const struct attribute_group iio_sysfs_trigger_attr_group = { > + .attrs = iio_sysfs_trigger_attrs, > +}; > + > +static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = { > + &iio_sysfs_trigger_attr_group, > + NULL > +}; > + > +static const struct iio_trigger_ops iio_sysfs_trigger_ops = { > + .owner = THIS_MODULE, > +}; > + > +static int iio_sysfs_trigger_probe(int id) > +{ > + struct iio_sysfs_trig *t; > + int ret; > + bool foundit = false; > + mutex_lock(&iio_syfs_trig_list_mut); > + list_for_each_entry(t, &iio_sysfs_trig_list, l) > + if (id == t->id) { > + foundit = true; > + break; > + } > + if (foundit) { > + ret = -EINVAL; > + goto out1; > + } > + t = kmalloc(sizeof(*t), GFP_KERNEL); > + if (t == NULL) { > + ret = -ENOMEM; > + goto out1; > + } > + t->id = id; > + t->trig = iio_trigger_alloc("sysfstrig%d", id); > + if (!t->trig) { > + ret = -ENOMEM; > + goto free_t; > + } > + > + t->trig->dev.groups = iio_sysfs_trigger_attr_groups; > + t->trig->ops = &iio_sysfs_trigger_ops; > + t->trig->dev.parent = &iio_sysfs_trig_dev; > + iio_trigger_set_drvdata(t->trig, t); > + > + init_irq_work(&t->work, iio_sysfs_trigger_work); > + > + ret = iio_trigger_register(t->trig); > + if (ret) > + goto out2; > + list_add(&t->l, &iio_sysfs_trig_list); > + __module_get(THIS_MODULE); > + mutex_unlock(&iio_syfs_trig_list_mut); > + return 0; > + > +out2: > + iio_trigger_put(t->trig); > +free_t: > + kfree(t); > +out1: > + mutex_unlock(&iio_syfs_trig_list_mut); > + return ret; > +} > + > +static int iio_sysfs_trigger_remove(int id) > +{ > + bool foundit = false; > + struct iio_sysfs_trig *t; > + mutex_lock(&iio_syfs_trig_list_mut); > + list_for_each_entry(t, &iio_sysfs_trig_list, l) > + if (id == t->id) { > + foundit = true; > + break; > + } > + if (!foundit) { > + mutex_unlock(&iio_syfs_trig_list_mut); > + return -EINVAL; > + } > + > + iio_trigger_unregister(t->trig); > + iio_trigger_free(t->trig); > + > + list_del(&t->l); > + kfree(t); > + module_put(THIS_MODULE); > + mutex_unlock(&iio_syfs_trig_list_mut); > + return 0; > +} > + > + > +static int __init iio_sysfs_trig_init(void) > +{ > + device_initialize(&iio_sysfs_trig_dev); > + dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger"); > + return device_add(&iio_sysfs_trig_dev); > +} > +module_init(iio_sysfs_trig_init); > + > +static void __exit iio_sysfs_trig_exit(void) > +{ > + device_unregister(&iio_sysfs_trig_dev); > +} > +module_exit(iio_sysfs_trig_exit); > + > +MODULE_AUTHOR("Michael Hennerich <hennerich@xxxxxxxxxxxxxxxxxxxx>"); > +MODULE_DESCRIPTION("Sysfs based trigger for the iio subsystem"); > +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("platform:iio-trig-sysfs"); > diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig > index d44d3ad..d0ae99c 100644 > --- a/drivers/staging/iio/trigger/Kconfig > +++ b/drivers/staging/iio/trigger/Kconfig > @@ -18,17 +18,6 @@ config IIO_GPIO_TRIGGER > help > Provides support for using GPIO pins as IIO triggers. > > -config IIO_SYSFS_TRIGGER > - tristate "SYSFS trigger" > - depends on SYSFS > - select IRQ_WORK > - help > - Provides support for using SYSFS entry as IIO triggers. > - If unsure, say N (but it's safe to say "Y"). > - > - To compile this driver as a module, choose M here: the > - module will be called iio-trig-sysfs. > - > config IIO_BFIN_TMR_TRIGGER > tristate "Blackfin TIMER trigger" > depends on BLACKFIN > diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile > index b088b57..8a53041 100644 > --- a/drivers/staging/iio/trigger/Makefile > +++ b/drivers/staging/iio/trigger/Makefile > @@ -4,5 +4,4 @@ > > obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o > obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o > -obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o > obj-$(CONFIG_IIO_BFIN_TMR_TRIGGER) += iio-trig-bfin-timer.o > diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c > deleted file mode 100644 > index b727bde..0000000 > --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c > +++ /dev/null > @@ -1,227 +0,0 @@ > -/* > - * Copyright 2011 Analog Devices Inc. > - * > - * Licensed under the GPL-2. > - * > - */ > - > -#include <linux/kernel.h> > -#include <linux/module.h> > -#include <linux/platform_device.h> > -#include <linux/slab.h> > -#include <linux/list.h> > -#include <linux/irq_work.h> > - > -#include <linux/iio/iio.h> > -#include <linux/iio/trigger.h> > - > -struct iio_sysfs_trig { > - struct iio_trigger *trig; > - struct irq_work work; > - int id; > - struct list_head l; > -}; > - > -static LIST_HEAD(iio_sysfs_trig_list); > -static DEFINE_MUTEX(iio_syfs_trig_list_mut); > - > -static int iio_sysfs_trigger_probe(int id); > -static ssize_t iio_sysfs_trig_add(struct device *dev, > - struct device_attribute *attr, > - const char *buf, > - size_t len) > -{ > - int ret; > - unsigned long input; > - > - ret = strict_strtoul(buf, 10, &input); > - if (ret) > - return ret; > - ret = iio_sysfs_trigger_probe(input); > - if (ret) > - return ret; > - return len; > -} > -static DEVICE_ATTR(add_trigger, S_IWUSR, NULL, &iio_sysfs_trig_add); > - > -static int iio_sysfs_trigger_remove(int id); > -static ssize_t iio_sysfs_trig_remove(struct device *dev, > - struct device_attribute *attr, > - const char *buf, > - size_t len) > -{ > - int ret; > - unsigned long input; > - > - ret = strict_strtoul(buf, 10, &input); > - if (ret) > - return ret; > - ret = iio_sysfs_trigger_remove(input); > - if (ret) > - return ret; > - return len; > -} > - > -static DEVICE_ATTR(remove_trigger, S_IWUSR, NULL, &iio_sysfs_trig_remove); > - > -static struct attribute *iio_sysfs_trig_attrs[] = { > - &dev_attr_add_trigger.attr, > - &dev_attr_remove_trigger.attr, > - NULL, > -}; > - > -static const struct attribute_group iio_sysfs_trig_group = { > - .attrs = iio_sysfs_trig_attrs, > -}; > - > -static const struct attribute_group *iio_sysfs_trig_groups[] = { > - &iio_sysfs_trig_group, > - NULL > -}; > - > - > -/* Nothing to actually do upon release */ > -static void iio_trigger_sysfs_release(struct device *dev) > -{ > -} > - > -static struct device iio_sysfs_trig_dev = { > - .bus = &iio_bus_type, > - .groups = iio_sysfs_trig_groups, > - .release = &iio_trigger_sysfs_release, > -}; > - > -static void iio_sysfs_trigger_work(struct irq_work *work) > -{ > - struct iio_sysfs_trig *trig = container_of(work, struct iio_sysfs_trig, > - work); > - > - iio_trigger_poll(trig->trig, 0); > -} > - > -static ssize_t iio_sysfs_trigger_poll(struct device *dev, > - struct device_attribute *attr, const char *buf, size_t count) > -{ > - struct iio_trigger *trig = to_iio_trigger(dev); > - struct iio_sysfs_trig *sysfs_trig = iio_trigger_get_drvdata(trig); > - > - irq_work_queue(&sysfs_trig->work); > - > - return count; > -} > - > -static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll); > - > -static struct attribute *iio_sysfs_trigger_attrs[] = { > - &dev_attr_trigger_now.attr, > - NULL, > -}; > - > -static const struct attribute_group iio_sysfs_trigger_attr_group = { > - .attrs = iio_sysfs_trigger_attrs, > -}; > - > -static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = { > - &iio_sysfs_trigger_attr_group, > - NULL > -}; > - > -static const struct iio_trigger_ops iio_sysfs_trigger_ops = { > - .owner = THIS_MODULE, > -}; > - > -static int iio_sysfs_trigger_probe(int id) > -{ > - struct iio_sysfs_trig *t; > - int ret; > - bool foundit = false; > - mutex_lock(&iio_syfs_trig_list_mut); > - list_for_each_entry(t, &iio_sysfs_trig_list, l) > - if (id == t->id) { > - foundit = true; > - break; > - } > - if (foundit) { > - ret = -EINVAL; > - goto out1; > - } > - t = kmalloc(sizeof(*t), GFP_KERNEL); > - if (t == NULL) { > - ret = -ENOMEM; > - goto out1; > - } > - t->id = id; > - t->trig = iio_trigger_alloc("sysfstrig%d", id); > - if (!t->trig) { > - ret = -ENOMEM; > - goto free_t; > - } > - > - t->trig->dev.groups = iio_sysfs_trigger_attr_groups; > - t->trig->ops = &iio_sysfs_trigger_ops; > - t->trig->dev.parent = &iio_sysfs_trig_dev; > - iio_trigger_set_drvdata(t->trig, t); > - > - init_irq_work(&t->work, iio_sysfs_trigger_work); > - > - ret = iio_trigger_register(t->trig); > - if (ret) > - goto out2; > - list_add(&t->l, &iio_sysfs_trig_list); > - __module_get(THIS_MODULE); > - mutex_unlock(&iio_syfs_trig_list_mut); > - return 0; > - > -out2: > - iio_trigger_put(t->trig); > -free_t: > - kfree(t); > -out1: > - mutex_unlock(&iio_syfs_trig_list_mut); > - return ret; > -} > - > -static int iio_sysfs_trigger_remove(int id) > -{ > - bool foundit = false; > - struct iio_sysfs_trig *t; > - mutex_lock(&iio_syfs_trig_list_mut); > - list_for_each_entry(t, &iio_sysfs_trig_list, l) > - if (id == t->id) { > - foundit = true; > - break; > - } > - if (!foundit) { > - mutex_unlock(&iio_syfs_trig_list_mut); > - return -EINVAL; > - } > - > - iio_trigger_unregister(t->trig); > - iio_trigger_free(t->trig); > - > - list_del(&t->l); > - kfree(t); > - module_put(THIS_MODULE); > - mutex_unlock(&iio_syfs_trig_list_mut); > - return 0; > -} > - > - > -static int __init iio_sysfs_trig_init(void) > -{ > - device_initialize(&iio_sysfs_trig_dev); > - dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger"); > - return device_add(&iio_sysfs_trig_dev); > -} > -module_init(iio_sysfs_trig_init); > - > -static void __exit iio_sysfs_trig_exit(void) > -{ > - device_unregister(&iio_sysfs_trig_dev); > -} > -module_exit(iio_sysfs_trig_exit); > - > -MODULE_AUTHOR("Michael Hennerich <hennerich@xxxxxxxxxxxxxxxxxxxx>"); > -MODULE_DESCRIPTION("Sysfs based trigger for the iio subsystem"); > -MODULE_LICENSE("GPL v2"); > -MODULE_ALIAS("platform:iio-trig-sysfs"); > -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html