diff options
author | Jacek Anaszewski <j.anaszewski@samsung.com> | 2013-08-16 09:11:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2013-08-17 14:34:52 -0400 |
commit | d536321df392ee0db6a5e92d98f0303020315f40 (patch) | |
tree | c3616492e72328c7a76ab22445d61f9bb167628c /drivers/iio/industrialio-trigger.c | |
parent | 1696f36482e7063051a1dad86a54be83fd847f4f (diff) |
iio: trigger: implement devm_iio_trigger_alloc/devm_iio_triger_free
Add a resource managed devm_iio_trigger_alloc()/devm_iio_triger_free()
to automatically clean up triggers allocated by IIO drivers, thus
leading to simplified IIO drivers code.
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Signed-off-by: Kyunmin Park <kyungmin.park@samsung.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
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 0dd9bb873130..bf5e70a32d3f 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) | |||
424 | trig->subirqs[d->irq - trig->subirq_base].enabled = true; | 424 | trig->subirqs[d->irq - trig->subirq_base].enabled = true; |
425 | } | 425 | } |
426 | 426 | ||
427 | struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) | 427 | static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) |
428 | { | 428 | { |
429 | va_list vargs; | ||
430 | struct iio_trigger *trig; | 429 | struct iio_trigger *trig; |
431 | trig = kzalloc(sizeof *trig, GFP_KERNEL); | 430 | trig = kzalloc(sizeof *trig, GFP_KERNEL); |
432 | if (trig) { | 431 | if (trig) { |
@@ -444,9 +443,8 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) | |||
444 | kfree(trig); | 443 | kfree(trig); |
445 | return NULL; | 444 | return NULL; |
446 | } | 445 | } |
447 | va_start(vargs, fmt); | 446 | |
448 | trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); | 447 | trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); |
449 | va_end(vargs); | ||
450 | if (trig->name == NULL) { | 448 | if (trig->name == NULL) { |
451 | irq_free_descs(trig->subirq_base, | 449 | irq_free_descs(trig->subirq_base, |
452 | CONFIG_IIO_CONSUMERS_PER_TRIGGER); | 450 | CONFIG_IIO_CONSUMERS_PER_TRIGGER); |
@@ -467,6 +465,19 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) | |||
467 | } | 465 | } |
468 | get_device(&trig->dev); | 466 | get_device(&trig->dev); |
469 | } | 467 | } |
468 | |||
469 | return trig; | ||
470 | } | ||
471 | |||
472 | struct iio_trigger *iio_trigger_alloc(const char *fmt, ...) | ||
473 | { | ||
474 | struct iio_trigger *trig; | ||
475 | va_list vargs; | ||
476 | |||
477 | va_start(vargs, fmt); | ||
478 | trig = viio_trigger_alloc(fmt, vargs); | ||
479 | va_end(vargs); | ||
480 | |||
470 | return trig; | 481 | return trig; |
471 | } | 482 | } |
472 | EXPORT_SYMBOL(iio_trigger_alloc); | 483 | EXPORT_SYMBOL(iio_trigger_alloc); |
@@ -478,6 +489,59 @@ void iio_trigger_free(struct iio_trigger *trig) | |||
478 | } | 489 | } |
479 | EXPORT_SYMBOL(iio_trigger_free); | 490 | EXPORT_SYMBOL(iio_trigger_free); |
480 | 491 | ||
492 | static void devm_iio_trigger_release(struct device *dev, void *res) | ||
493 | { | ||
494 | iio_trigger_free(*(struct iio_trigger **)res); | ||
495 | } | ||
496 | |||
497 | static int devm_iio_trigger_match(struct device *dev, void *res, void *data) | ||
498 | { | ||
499 | struct iio_trigger **r = res; | ||
500 | |||
501 | if (!r || !*r) { | ||
502 | WARN_ON(!r || !*r); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | return *r == data; | ||
507 | } | ||
508 | |||
509 | struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, | ||
510 | const char *fmt, ...) | ||
511 | { | ||
512 | struct iio_trigger **ptr, *trig; | ||
513 | va_list vargs; | ||
514 | |||
515 | ptr = devres_alloc(devm_iio_trigger_release, sizeof(*ptr), | ||
516 | GFP_KERNEL); | ||
517 | if (!ptr) | ||
518 | return NULL; | ||
519 | |||
520 | /* use raw alloc_dr for kmalloc caller tracing */ | ||
521 | va_start(vargs, fmt); | ||
522 | trig = viio_trigger_alloc(fmt, vargs); | ||
523 | va_end(vargs); | ||
524 | if (trig) { | ||
525 | *ptr = trig; | ||
526 | devres_add(dev, ptr); | ||
527 | } else { | ||
528 | devres_free(ptr); | ||
529 | } | ||
530 | |||
531 | return trig; | ||
532 | } | ||
533 | EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc); | ||
534 | |||
535 | void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig) | ||
536 | { | ||
537 | int rc; | ||
538 | |||
539 | rc = devres_release(dev, devm_iio_trigger_release, | ||
540 | devm_iio_trigger_match, iio_trig); | ||
541 | WARN_ON(rc); | ||
542 | } | ||
543 | EXPORT_SYMBOL_GPL(devm_iio_trigger_free); | ||
544 | |||
481 | void iio_device_register_trigger_consumer(struct iio_dev *indio_dev) | 545 | void iio_device_register_trigger_consumer(struct iio_dev *indio_dev) |
482 | { | 546 | { |
483 | indio_dev->groups[indio_dev->groupcounter++] = | 547 | indio_dev->groups[indio_dev->groupcounter++] = |