linux/drivers/iio/buffer/industrialio-triggered-buffer.c
<<
>>
Prefs
   1 /*
   2 * Copyright (c) 2012 Analog Devices, Inc.
   3 *  Author: Lars-Peter Clausen <lars@metafoo.de>
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 as published by
   7 * the Free Software Foundation.
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/export.h>
  12#include <linux/module.h>
  13#include <linux/iio/iio.h>
  14#include <linux/iio/buffer.h>
  15#include <linux/iio/kfifo_buf.h>
  16#include <linux/iio/triggered_buffer.h>
  17#include <linux/iio/trigger_consumer.h>
  18
  19static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
  20        .postenable = &iio_triggered_buffer_postenable,
  21        .predisable = &iio_triggered_buffer_predisable,
  22};
  23
  24/**
  25 * iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc
  26 * @indio_dev:          IIO device structure
  27 * @h:                  Function which will be used as pollfunc top half
  28 * @thread:             Function which will be used as pollfunc bottom half
  29 * @setup_ops:          Buffer setup functions to use for this device.
  30 *                      If NULL the default setup functions for triggered
  31 *                      buffers will be used.
  32 *
  33 * This function combines some common tasks which will normally be performed
  34 * when setting up a triggered buffer. It will allocate the buffer and the
  35 * pollfunc.
  36 *
  37 * Before calling this function the indio_dev structure should already be
  38 * completely initialized, but not yet registered. In practice this means that
  39 * this function should be called right before iio_device_register().
  40 *
  41 * To free the resources allocated by this function call
  42 * iio_triggered_buffer_cleanup().
  43 */
  44int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
  45        irqreturn_t (*h)(int irq, void *p),
  46        irqreturn_t (*thread)(int irq, void *p),
  47        const struct iio_buffer_setup_ops *setup_ops)
  48{
  49        struct iio_buffer *buffer;
  50        int ret;
  51
  52        buffer = iio_kfifo_allocate();
  53        if (!buffer) {
  54                ret = -ENOMEM;
  55                goto error_ret;
  56        }
  57
  58        iio_device_attach_buffer(indio_dev, buffer);
  59
  60        indio_dev->pollfunc = iio_alloc_pollfunc(h,
  61                                                 thread,
  62                                                 IRQF_ONESHOT,
  63                                                 indio_dev,
  64                                                 "%s_consumer%d",
  65                                                 indio_dev->name,
  66                                                 indio_dev->id);
  67        if (indio_dev->pollfunc == NULL) {
  68                ret = -ENOMEM;
  69                goto error_kfifo_free;
  70        }
  71
  72        /* Ring buffer functions - here trigger setup related */
  73        if (setup_ops)
  74                indio_dev->setup_ops = setup_ops;
  75        else
  76                indio_dev->setup_ops = &iio_triggered_buffer_setup_ops;
  77
  78        /* Flag that polled ring buffering is possible */
  79        indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
  80
  81        return 0;
  82
  83error_kfifo_free:
  84        iio_kfifo_free(indio_dev->buffer);
  85error_ret:
  86        return ret;
  87}
  88EXPORT_SYMBOL(iio_triggered_buffer_setup);
  89
  90/**
  91 * iio_triggered_buffer_cleanup() - Free resources allocated by iio_triggered_buffer_setup()
  92 * @indio_dev: IIO device structure
  93 */
  94void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
  95{
  96        iio_dealloc_pollfunc(indio_dev->pollfunc);
  97        iio_kfifo_free(indio_dev->buffer);
  98}
  99EXPORT_SYMBOL(iio_triggered_buffer_cleanup);
 100
 101static void devm_iio_triggered_buffer_clean(struct device *dev, void *res)
 102{
 103        iio_triggered_buffer_cleanup(*(struct iio_dev **)res);
 104}
 105
 106int devm_iio_triggered_buffer_setup(struct device *dev,
 107                                    struct iio_dev *indio_dev,
 108                                    irqreturn_t (*h)(int irq, void *p),
 109                                    irqreturn_t (*thread)(int irq, void *p),
 110                                    const struct iio_buffer_setup_ops *ops)
 111{
 112        struct iio_dev **ptr;
 113        int ret;
 114
 115        ptr = devres_alloc(devm_iio_triggered_buffer_clean, sizeof(*ptr),
 116                           GFP_KERNEL);
 117        if (!ptr)
 118                return -ENOMEM;
 119
 120        *ptr = indio_dev;
 121
 122        ret = iio_triggered_buffer_setup(indio_dev, h, thread, ops);
 123        if (!ret)
 124                devres_add(dev, ptr);
 125        else
 126                devres_free(ptr);
 127
 128        return ret;
 129}
 130EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_setup);
 131
 132void devm_iio_triggered_buffer_cleanup(struct device *dev,
 133                                       struct iio_dev *indio_dev)
 134{
 135        int rc;
 136
 137        rc = devres_release(dev, devm_iio_triggered_buffer_clean,
 138                            devm_iio_device_match, indio_dev);
 139        WARN_ON(rc);
 140}
 141EXPORT_SYMBOL_GPL(devm_iio_triggered_buffer_cleanup);
 142
 143MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 144MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers");
 145MODULE_LICENSE("GPL");
 146