diff options
Diffstat (limited to 'drivers/staging/iio/trigger')
-rw-r--r-- | drivers/staging/iio/trigger/Kconfig | 1 | ||||
-rw-r--r-- | drivers/staging/iio/trigger/iio-trig-bfin-timer.c | 22 | ||||
-rw-r--r-- | drivers/staging/iio/trigger/iio-trig-gpio.c | 25 | ||||
-rw-r--r-- | drivers/staging/iio/trigger/iio-trig-periodic-rtc.c | 24 | ||||
-rw-r--r-- | drivers/staging/iio/trigger/iio-trig-sysfs.c | 169 |
5 files changed, 151 insertions, 90 deletions
diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig index c33777e0a8b3..b8abf5473ddc 100644 --- a/drivers/staging/iio/trigger/Kconfig +++ b/drivers/staging/iio/trigger/Kconfig @@ -31,6 +31,7 @@ config IIO_SYSFS_TRIGGER config IIO_BFIN_TMR_TRIGGER tristate "Blackfin TIMER trigger" depends on BLACKFIN + select BFIN_GPTIMERS help Provides support for using a Blackfin timer as IIO triggers. If unsure, say N (but it's safe to say "Y"). diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 583bef0936e8..4f1729565582 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -106,11 +106,9 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show, iio_bfin_tmr_frequency_store); -static IIO_TRIGGER_NAME_ATTR; static struct attribute *iio_bfin_tmr_trigger_attrs[] = { &dev_attr_frequency.attr, - &dev_attr_name.attr, NULL, }; @@ -118,6 +116,11 @@ static const struct attribute_group iio_bfin_tmr_trigger_attr_group = { .attrs = iio_bfin_tmr_trigger_attrs, }; +static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = { + &iio_bfin_tmr_trigger_attr_group, + NULL +}; + static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid) { @@ -165,24 +168,18 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) st->timer_num = ret; st->t = &iio_bfin_timer_code[st->timer_num]; - st->trig = iio_allocate_trigger(); + st->trig = iio_allocate_trigger("bfintmr%d", st->timer_num); if (!st->trig) { ret = -ENOMEM; goto out1; } st->trig->private_data = st; - st->trig->control_attrs = &iio_bfin_tmr_trigger_attr_group; st->trig->owner = THIS_MODULE; - st->trig->name = kasprintf(GFP_KERNEL, "bfintmr%d", st->timer_num); - if (st->trig->name == NULL) { - ret = -ENOMEM; - goto out2; - } - + st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups; ret = iio_trigger_register(st->trig); if (ret) - goto out3; + goto out2; ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr, 0, st->trig->name, st); @@ -201,8 +198,6 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) return 0; out4: iio_trigger_unregister(st->trig); -out3: - kfree(st->trig->name); out2: iio_put_trigger(st->trig); out1: @@ -218,7 +213,6 @@ static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev) disable_gptimers(st->t->bit); free_irq(st->irq, st); iio_trigger_unregister(st->trig); - kfree(st->trig->name); iio_put_trigger(st->trig); kfree(st); diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index 2ce95e964cfd..b188635c3460 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -47,17 +47,6 @@ static irqreturn_t iio_gpio_trigger_poll(int irq, void *private) return IRQ_HANDLED; } -static IIO_TRIGGER_NAME_ATTR; - -static struct attribute *iio_gpio_trigger_attrs[] = { - &dev_attr_name.attr, - NULL, -}; - -static const struct attribute_group iio_gpio_trigger_attr_group = { - .attrs = iio_gpio_trigger_attrs, -}; - static int iio_gpio_trigger_probe(struct platform_device *pdev) { struct iio_gpio_trigger_info *trig_info; @@ -79,7 +68,7 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) for (irq = irq_res->start; irq <= irq_res->end; irq++) { - trig = iio_allocate_trigger(); + trig = iio_allocate_trigger("irqtrig%d", irq); if (!trig) { ret = -ENOMEM; goto error_free_completed_registrations; @@ -90,21 +79,15 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) ret = -ENOMEM; goto error_put_trigger; } - trig->control_attrs = &iio_gpio_trigger_attr_group; trig->private_data = trig_info; trig_info->irq = irq; trig->owner = THIS_MODULE; - trig->name = kasprintf(GFP_KERNEL, "irqtrig%d", irq); - if (trig->name == NULL) { - ret = -ENOMEM; - goto error_free_trig_info; - } ret = request_irq(irq, iio_gpio_trigger_poll, irqflags, trig->name, trig); if (ret) { dev_err(&pdev->dev, "request IRQ-%d failed", irq); - goto error_free_name; + goto error_free_trig_info; } ret = iio_trigger_register(trig); @@ -124,8 +107,6 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) /* First clean up the partly allocated trigger */ error_release_irq: free_irq(irq, trig); -error_free_name: - kfree(trig->name); error_free_trig_info: kfree(trig_info); error_put_trigger: @@ -138,7 +119,6 @@ error_free_completed_registrations: alloc_list) { trig_info = trig->private_data; free_irq(gpio_to_irq(trig_info->irq), trig); - kfree(trig->name); kfree(trig_info); iio_trigger_unregister(trig); } @@ -159,7 +139,6 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev) trig_info = trig->private_data; iio_trigger_unregister(trig); free_irq(trig_info->irq, trig); - kfree(trig->name); kfree(trig_info); iio_put_trigger(trig); } diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 24f174e1cda5..01cf7e20b515 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -72,20 +72,24 @@ error_ret: return ret; } -static IIO_TRIGGER_NAME_ATTR; static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_trig_periodic_read_freq, iio_trig_periodic_write_freq); static struct attribute *iio_trig_prtc_attrs[] = { &dev_attr_frequency.attr, - &dev_attr_name.attr, NULL, }; + static const struct attribute_group iio_trig_prtc_attr_group = { .attrs = iio_trig_prtc_attrs, }; +static const struct attribute_group *iio_trig_prtc_attr_groups[] = { + &iio_trig_prtc_attr_group, + NULL +}; + static void iio_prtc_trigger_poll(void *private_data) { /* Timestamp is not provided currently */ @@ -103,7 +107,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev) for (i = 0;; i++) { if (pdata[i] == NULL) break; - trig = iio_allocate_trigger(); + trig = iio_allocate_trigger("periodic%s", pdata[i]); if (!trig) { ret = -ENOMEM; goto error_free_completed_registrations; @@ -118,25 +122,19 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev) trig->private_data = trig_info; trig->owner = THIS_MODULE; trig->set_trigger_state = &iio_trig_periodic_rtc_set_state; - trig->name = kasprintf(GFP_KERNEL, "periodic%s", pdata[i]); - if (trig->name == NULL) { - ret = -ENOMEM; - goto error_free_trig_info; - } - /* RTC access */ trig_info->rtc = rtc_class_open(pdata[i]); if (trig_info->rtc == NULL) { ret = -EINVAL; - goto error_free_name; + goto error_free_trig_info; } trig_info->task.func = iio_prtc_trigger_poll; trig_info->task.private_data = trig; ret = rtc_irq_register(trig_info->rtc, &trig_info->task); if (ret) goto error_close_rtc; - trig->control_attrs = &iio_trig_prtc_attr_group; + trig->dev.groups = iio_trig_prtc_attr_groups; ret = iio_trigger_register(trig); if (ret) goto error_unregister_rtc_irq; @@ -146,8 +144,6 @@ error_unregister_rtc_irq: rtc_irq_unregister(trig_info->rtc, &trig_info->task); error_close_rtc: rtc_class_close(trig_info->rtc); -error_free_name: - kfree(trig->name); error_free_trig_info: kfree(trig_info); error_put_trigger_and_remove_from_list: @@ -161,7 +157,6 @@ error_free_completed_registrations: trig_info = trig->private_data; rtc_irq_unregister(trig_info->rtc, &trig_info->task); rtc_class_close(trig_info->rtc); - kfree(trig->name); kfree(trig_info); iio_trigger_unregister(trig); } @@ -180,7 +175,6 @@ static int iio_trig_periodic_rtc_remove(struct platform_device *dev) trig_info = trig->private_data; rtc_irq_unregister(trig_info->rtc, &trig_info->task); rtc_class_close(trig_info->rtc); - kfree(trig->name); kfree(trig_info); iio_trigger_unregister(trig); } diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c index 127a2a33e4db..47248cd1fa0d 100644 --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -9,25 +9,92 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/list.h> #include "../iio.h" #include "../trigger.h" +struct iio_sysfs_trig { + struct iio_trigger *trig; + 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 +}; + +static struct device iio_sysfs_trig_dev = { + .bus = &iio_bus_type, + .groups = iio_sysfs_trig_groups, +}; + static ssize_t iio_sysfs_trigger_poll(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_trigger *trig = dev_get_drvdata(dev); - iio_trigger_poll(trig, 0); + iio_trigger_poll_chained(trig, 0); return count; } static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll); -static IIO_TRIGGER_NAME_ATTR; static struct attribute *iio_sysfs_trigger_attrs[] = { &dev_attr_trigger_now.attr, - &dev_attr_name.attr, NULL, }; @@ -35,70 +102,96 @@ static const struct attribute_group iio_sysfs_trigger_attr_group = { .attrs = iio_sysfs_trigger_attrs, }; -static int __devinit iio_sysfs_trigger_probe(struct platform_device *pdev) +static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = { + &iio_sysfs_trigger_attr_group, + NULL +}; + +static int iio_sysfs_trigger_probe(int id) { - struct iio_trigger *trig; + struct iio_sysfs_trig *t; int ret; - - trig = iio_allocate_trigger(); - if (!trig) { + 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; } - - trig->control_attrs = &iio_sysfs_trigger_attr_group; - trig->owner = THIS_MODULE; - trig->name = kasprintf(GFP_KERNEL, "sysfstrig%d", pdev->id); - if (trig->name == NULL) { + t->id = id; + t->trig = iio_allocate_trigger("sysfstrig%d", id); + if (!t->trig) { ret = -ENOMEM; - goto out2; + goto free_t; } - ret = iio_trigger_register(trig); - if (ret) - goto out3; - - platform_set_drvdata(pdev, trig); + t->trig->dev.groups = iio_sysfs_trigger_attr_groups; + t->trig->owner = THIS_MODULE; + t->trig->dev.parent = &iio_sysfs_trig_dev; + 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; -out3: - kfree(trig->name); + out2: - iio_put_trigger(trig); + iio_put_trigger(t->trig); +free_t: + kfree(t); out1: - + mutex_unlock(&iio_syfs_trig_list_mut); return ret; } -static int __devexit iio_sysfs_trigger_remove(struct platform_device *pdev) +static int iio_sysfs_trigger_remove(int id) { - struct iio_trigger *trig = platform_get_drvdata(pdev); + 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(trig); - kfree(trig->name); - iio_put_trigger(trig); + iio_trigger_unregister(t->trig); + iio_free_trigger(t->trig); + list_del(&t->l); + kfree(t); + module_put(THIS_MODULE); + mutex_unlock(&iio_syfs_trig_list_mut); return 0; } -static struct platform_driver iio_sysfs_trigger_driver = { - .driver = { - .name = "iio_sysfs_trigger", - .owner = THIS_MODULE, - }, - .probe = iio_sysfs_trigger_probe, - .remove = __devexit_p(iio_sysfs_trigger_remove), -}; static int __init iio_sysfs_trig_init(void) { - return platform_driver_register(&iio_sysfs_trigger_driver); + 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) { - platform_driver_unregister(&iio_sysfs_trigger_driver); + device_unregister(&iio_sysfs_trig_dev); } module_exit(iio_sysfs_trig_exit); |