diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-23 09:23:23 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-23 09:23:23 +0100 |
commit | 08cad739ba28a986a753681105ce1885ccc392eb (patch) | |
tree | bada91735d360eb5c70ba405a1a6c4b98ae87217 /drivers/iio/industrialio-trigger.c | |
parent | 994261dc8f3dfcd19feecafae3040e932c8f90cf (diff) | |
parent | 10e840dfb0b7fc345082dd9e5fff3c1c02e7690e (diff) |
Merge tag 'iio-for-4.11b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into work-next
Jonathan writes:
Second round of IIO new device support, cleanups and features for the 4.11 cycle
New device support:
* lsm6dsx imu
- new driver and bindings.
* max11100 adc
- new driver and bindings.
* tlc4541
- new driver
* tmp007 thermopile
- new driver.
Core
* in kernel interfaces
- pass through raw values if no scaling provided and a processed value is
requested.
* trigger
- close a race condition in acquiring trigger reference.
- constify device_type structures.
- rework the viio_trigger_alloc function to be much neater and easier to
read.
- free trigger resources correctly on some error paths. Avoids putting a
module we don't have.
Documentation
* ABI
- specify a unit for proximity measurements.
Cleanups and features
* ads1015
- constify iio_info structure.
* ads7950 cleanups following merge in previous pull
- Add device tree bindings
- Drop the ti prefix from the module name in common with other drivers.
- Change regulator name to vref to match datasheet and other drivers.
* ak8974
- remove a redundant zero timeout check.
* bmi160
- use variable names for sizeof instead of types.
* cm3605
- mark PM functions as __maybe_unused to avoid a build warning.
* isl29028 (on it's way towards moving out of staging).
- alignment fixes and newline improvements.
- combine proxim_get and read_proxim for simpler code.
- drop unused ISL29028_DEV_ATTR macro
- move some error logging into functions to cut out repitition.
- make error messages more consistent.
- tidy up some brackets.
- drop the enable flag that nothing uses.
- only set proximity rate and ALS scale when relevant channel type is enabled.
- runtime pm support.
* lsm6dsx
- fix wrong values for gyro sensitivitiy.
* mag3110
- claim direct mode during sysfs reads to avoid a race condition.
* max1363
- export OF device table IDs as module aliases.
* max30100
- use msleep for long uncritical delays.
* mcp4531
- export OF device table as module aliases.
* ms5611
- claim direct mode during sysfs reads to avoid a race condition.
* opt3001
- export OF device table as module aliases.
* sx9500
- claim direct mode during oversampling changes to avoid a race condition.
Diffstat (limited to 'drivers/iio/industrialio-trigger.c')
-rw-r--r-- | drivers/iio/industrialio-trigger.c | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 978729f6d7c4..978e1592c2a3 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -147,8 +147,7 @@ static struct iio_trigger *__iio_trigger_find_by_name(const char *name) return NULL; } -static struct iio_trigger *iio_trigger_find_by_name(const char *name, - size_t len) +static struct iio_trigger *iio_trigger_acquire_by_name(const char *name) { struct iio_trigger *trig = NULL, *iter; @@ -156,6 +155,7 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name, list_for_each_entry(iter, &iio_trigger_list, list) if (sysfs_streq(iter->name, name)) { trig = iter; + iio_trigger_get(trig); break; } mutex_unlock(&iio_trigger_list_lock); @@ -416,20 +416,22 @@ static ssize_t iio_trigger_write_current(struct device *dev, } mutex_unlock(&indio_dev->mlock); - trig = iio_trigger_find_by_name(buf, len); - if (oldtrig == trig) - return len; + trig = iio_trigger_acquire_by_name(buf); + if (oldtrig == trig) { + ret = len; + goto out_trigger_put; + } if (trig && indio_dev->info->validate_trigger) { ret = indio_dev->info->validate_trigger(indio_dev, trig); if (ret) - return ret; + goto out_trigger_put; } if (trig && trig->ops->validate_device) { ret = trig->ops->validate_device(trig, indio_dev); if (ret) - return ret; + goto out_trigger_put; } indio_dev->trig = trig; @@ -441,13 +443,16 @@ static ssize_t iio_trigger_write_current(struct device *dev, iio_trigger_put(oldtrig); } if (indio_dev->trig) { - iio_trigger_get(indio_dev->trig); if (indio_dev->modes & INDIO_EVENT_TRIGGERED) iio_trigger_attach_poll_func(indio_dev->trig, indio_dev->pollfunc_event); } return len; + +out_trigger_put: + iio_trigger_put(trig); + return ret; } static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, @@ -487,7 +492,7 @@ static void iio_trig_release(struct device *device) kfree(trig); } -static struct device_type iio_trig_type = { +static const struct device_type iio_trig_type = { .release = iio_trig_release, .groups = iio_trig_dev_groups, }; @@ -513,46 +518,45 @@ static void iio_trig_subirqunmask(struct irq_data *d) static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) { struct iio_trigger *trig; + int i; + trig = kzalloc(sizeof *trig, GFP_KERNEL); - if (trig) { - int i; - trig->dev.type = &iio_trig_type; - trig->dev.bus = &iio_bus_type; - device_initialize(&trig->dev); - - mutex_init(&trig->pool_lock); - trig->subirq_base - = irq_alloc_descs(-1, 0, - CONFIG_IIO_CONSUMERS_PER_TRIGGER, - 0); - if (trig->subirq_base < 0) { - kfree(trig); - return NULL; - } + if (!trig) + return NULL; - trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); - if (trig->name == NULL) { - irq_free_descs(trig->subirq_base, - CONFIG_IIO_CONSUMERS_PER_TRIGGER); - kfree(trig); - return NULL; - } - trig->subirq_chip.name = trig->name; - trig->subirq_chip.irq_mask = &iio_trig_subirqmask; - trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask; - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { - irq_set_chip(trig->subirq_base + i, - &trig->subirq_chip); - irq_set_handler(trig->subirq_base + i, - &handle_simple_irq); - irq_modify_status(trig->subirq_base + i, - IRQ_NOREQUEST | IRQ_NOAUTOEN, - IRQ_NOPROBE); - } - get_device(&trig->dev); + trig->dev.type = &iio_trig_type; + trig->dev.bus = &iio_bus_type; + device_initialize(&trig->dev); + + mutex_init(&trig->pool_lock); + trig->subirq_base = irq_alloc_descs(-1, 0, + CONFIG_IIO_CONSUMERS_PER_TRIGGER, + 0); + if (trig->subirq_base < 0) + goto free_trig; + + trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); + if (trig->name == NULL) + goto free_descs; + + trig->subirq_chip.name = trig->name; + trig->subirq_chip.irq_mask = &iio_trig_subirqmask; + trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask; + for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { + irq_set_chip(trig->subirq_base + i, &trig->subirq_chip); + irq_set_handler(trig->subirq_base + i, &handle_simple_irq); + irq_modify_status(trig->subirq_base + i, + IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); } + get_device(&trig->dev); return trig; + +free_descs: + irq_free_descs(trig->subirq_base, CONFIG_IIO_CONSUMERS_PER_TRIGGER); +free_trig: + kfree(trig); + return NULL; } struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) |