diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-09-27 11:56:14 -0300 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-09-27 11:56:14 -0300 |
commit | 1025c04cecd19882e28f16c4004034b475c372c5 (patch) | |
tree | 2b7402887e86d54bff5a123228c9059eae5e32bd /drivers/iio/industrialio-trigger.c | |
parent | 4375f1037d52602413142e290608d0d84671ad36 (diff) | |
parent | 5bcecf325378218a8e248bb6bcae96ec7362f8ef (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Conflicts:
net/bluetooth/hci_core.c
Diffstat (limited to 'drivers/iio/industrialio-trigger.c')
-rw-r--r-- | drivers/iio/industrialio-trigger.c | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 0dd9bb87313..bf5e70a32d3 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -424,9 +424,8 @@ static void iio_trig_subirqunmask(struct irq_data *d) trig->subirqs[d->irq - trig->subirq_base].enabled = true; } -struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) +static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) { - va_list vargs; struct iio_trigger *trig; trig = kzalloc(sizeof *trig, GFP_KERNEL); if (trig) { @@ -444,9 +443,8 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) kfree(trig); return NULL; } - va_start(vargs, fmt); + trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); - va_end(vargs); if (trig->name == NULL) { irq_free_descs(trig->subirq_base, CONFIG_IIO_CONSUMERS_PER_TRIGGER); @@ -467,6 +465,19 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) } get_device(&trig->dev); } + + return trig; +} + +struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) +{ + struct iio_trigger *trig; + va_list vargs; + + va_start(vargs, fmt); + trig = viio_trigger_alloc(fmt, vargs); + va_end(vargs); + return trig; } EXPORT_SYMBOL(iio_trigger_alloc); @@ -478,6 +489,59 @@ void iio_trigger_free(struct iio_trigger *trig) } EXPORT_SYMBOL(iio_trigger_free); +static void devm_iio_trigger_release(struct device *dev, void *res) +{ + iio_trigger_free(*(struct iio_trigger **)res); +} + +static int devm_iio_trigger_match(struct device *dev, void *res, void *data) +{ + struct iio_trigger **r = res; + + if (!r || !*r) { + WARN_ON(!r || !*r); + return 0; + } + + return *r == data; +} + +struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, + const char *fmt, ...) +{ + struct iio_trigger **ptr, *trig; + va_list vargs; + + ptr = devres_alloc(devm_iio_trigger_release, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return NULL; + + /* use raw alloc_dr for kmalloc caller tracing */ + va_start(vargs, fmt); + trig = viio_trigger_alloc(fmt, vargs); + va_end(vargs); + if (trig) { + *ptr = trig; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return trig; +} +EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc); + +void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig) +{ + int rc; + + rc = devres_release(dev, devm_iio_trigger_release, + devm_iio_trigger_match, iio_trig); + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_iio_trigger_free); + void iio_device_register_trigger_consumer(struct iio_dev *indio_dev) { indio_dev->groups[indio_dev->groupcounter++] = |