drivers/iio/buffer/industrialio-hw-consumer.c

Source file repositories/reference/linux-study-clean/drivers/iio/buffer/industrialio-hw-consumer.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/buffer/industrialio-hw-consumer.c
Extension
.c
Size
5156 bytes
Lines
217
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct iio_hw_consumer {
	struct list_head buffers;
	struct iio_channel *channels;
};

struct hw_consumer_buffer {
	struct list_head head;
	struct iio_dev *indio_dev;
	struct iio_buffer buffer;
};

static struct hw_consumer_buffer *iio_buffer_to_hw_consumer_buffer(
	struct iio_buffer *buffer)
{
	return container_of(buffer, struct hw_consumer_buffer, buffer);
}

static void iio_hw_buf_release(struct iio_buffer *buffer)
{
	struct hw_consumer_buffer *hw_buf =
		iio_buffer_to_hw_consumer_buffer(buffer);
	kfree(hw_buf);
}

static const struct iio_buffer_access_funcs iio_hw_buf_access = {
	.release = &iio_hw_buf_release,
	.modes = INDIO_BUFFER_HARDWARE,
};

static struct hw_consumer_buffer *iio_hw_consumer_get_buffer(
	struct iio_hw_consumer *hwc, struct iio_dev *indio_dev)
{
	struct hw_consumer_buffer *buf;

	list_for_each_entry(buf, &hwc->buffers, head) {
		if (buf->indio_dev == indio_dev)
			return buf;
	}

	buf = kzalloc_obj(*buf);
	if (!buf)
		return NULL;

	buf->buffer.access = &iio_hw_buf_access;
	buf->indio_dev = indio_dev;
	buf->buffer.scan_mask = bitmap_zalloc(iio_get_masklength(indio_dev),
					      GFP_KERNEL);
	if (!buf->buffer.scan_mask) {
		kfree(buf);
		return NULL;
	}

	iio_buffer_init(&buf->buffer);
	list_add_tail(&buf->head, &hwc->buffers);

	return buf;
}

/**
 * iio_hw_consumer_alloc() - Allocate IIO hardware consumer
 * @dev: Pointer to consumer device.
 *
 * Returns a valid iio_hw_consumer on success or a ERR_PTR() on failure.
 */
struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev)
{
	struct hw_consumer_buffer *buf, *tmp;
	struct iio_hw_consumer *hwc;
	struct iio_channel *chan;
	int ret;

	hwc = kzalloc_obj(*hwc);
	if (!hwc)
		return ERR_PTR(-ENOMEM);

	INIT_LIST_HEAD(&hwc->buffers);

	hwc->channels = iio_channel_get_all(dev);
	if (IS_ERR(hwc->channels)) {
		ret = PTR_ERR(hwc->channels);
		goto err_free_hwc;
	}

	chan = &hwc->channels[0];
	while (chan->indio_dev) {
		buf = iio_hw_consumer_get_buffer(hwc, chan->indio_dev);
		if (!buf) {
			ret = -ENOMEM;
			goto err_put_buffers;
		}

Annotation

Implementation Notes