All of lore.kernel.org
 help / color / mirror / Atom feed
From: Octavian Purdila <octavian.purdila@intel.com>
To: linux-iio@vger.kernel.org
Cc: Octavian Purdila <octavian.purdila@intel.com>
Subject: [PATCH v2 04/11] iio: add support for hardware fifo
Date: Sun, 21 Dec 2014 02:42:29 +0200	[thread overview]
Message-ID: <1419122556-8100-5-git-send-email-octavian.purdila@intel.com> (raw)
In-Reply-To: <1419122556-8100-1-git-send-email-octavian.purdila@intel.com>

Some devices have hardware buffers that can store a number of samples
for later consumption. Hardware usually provides interrupts to notify
the processor when the fifo is full or when it has reached a certain
threshold. This helps with reducing the number of interrupts to the
host processor and thus it helps decreasing the power consumption.

This patch adds support for hardware fifo to IIO by allowing the
drivers to register operations for flushing the hadware fifo and
setting the watermark level.

A driver implementing hardware fifo support must also provide a
watermark trigger which must contain "watermark" in its name.

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
---
 Documentation/ABI/testing/sysfs-bus-iio | 22 +++++++++++++++++
 drivers/iio/industrialio-buffer.c       | 44 ++++++++++++++++++++++++++++-----
 include/linux/iio/iio.h                 | 17 +++++++++++++
 3 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 7260f1f..6bb67ac 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1152,3 +1152,25 @@ Description:
 		Poll will block until the watermark is reached.
 		Blocking read will wait until the minimum between the requested
 		read amount or the low water mark is available.
+		If the device has a hardware fifo this value is going to be used
+		for the hardware fifo watermark as well.
+
+What:		/sys/bus/iio/devices/iio:deviceX/buffer/hwfifo-length
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		A single positive integer specifying the maximum number of
+		samples that the hardware fifo has. If the device does not
+		support hardware fifo this is zero.
+		When a device supports hardware fifo it will expose a trigger
+		with the name that contains "watermark"
+		(e.g. i2c-BMC150A:00-watermark-dev0).
+		To use the hardware fifo the user must set an appropriate value
+		in the buffer/length and buffer/low_watermark entries and select
+		the watermark trigger. At that poin the hardware fifo will be
+		enabled and the samples will be collected in a hardware buffer.
+		When the number of samples in the hardware fifo reaches the
+		watermark level the watermark trigger is issued and data is
+		flushed to the devices buffer.
+		A hardware buffer flush will also be triggered when reading from
+		the device buffer and there is not enough data available.
\ No newline at end of file
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index 7f74c7f..3da6d07 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -37,9 +37,17 @@ static bool iio_buffer_is_active(struct iio_buffer *buf)
 	return !list_empty(&buf->buffer_list);
 }
 
-static size_t iio_buffer_data_available(struct iio_buffer *buf)
+static bool iio_buffer_data_available(struct iio_dev *indio_dev,
+				      struct iio_buffer *buf, size_t required)
 {
-	return buf->access->data_available(buf);
+	size_t avail = buf->access->data_available(buf);
+
+	if (avail < required && indio_dev->hwfifo) {
+		indio_dev->hwfifo->flush(indio_dev);
+		avail = buf->access->data_available(buf);
+	}
+
+	return avail >= required;
 }
 
 /**
@@ -66,13 +74,13 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 
 	do {
 		if (filp->f_flags & O_NONBLOCK) {
-			if (!iio_buffer_data_available(rb)) {
+			if (!iio_buffer_data_available(indio_dev, rb, 1)) {
 				ret = -EAGAIN;
 				break;
 			}
 		} else {
 			ret = wait_event_interruptible(rb->pollq,
-			       iio_buffer_data_available(rb) >= to_read ||
+		            iio_buffer_data_available(indio_dev, rb, to_read) ||
 						       indio_dev->info == NULL);
 			if (ret)
 				return ret;
@@ -112,7 +120,7 @@ unsigned int iio_buffer_poll(struct file *filp,
 		return -ENODEV;
 
 	poll_wait(filp, &rb->pollq, wait);
-	if (iio_buffer_data_available(rb) >= rb->low_watermark)
+	if (iio_buffer_data_available(indio_dev, rb, rb->low_watermark))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
@@ -440,8 +448,14 @@ static ssize_t iio_buffer_write_length(struct device *dev,
 	if (buffer->length)
 		val = buffer->length;
 
-	if (val < buffer->low_watermark)
+	if (val < buffer->low_watermark) {
+		if (indio_dev->hwfifo) {
+			ret = indio_dev->hwfifo->set_watermark(indio_dev, val);
+			if (ret)
+				return ret;
+		}
 		buffer->low_watermark = val;
+	}
 
 	return len;
 }
@@ -811,6 +825,12 @@ static ssize_t iio_buffer_store_watermark(struct device *dev,
 		goto out;
 	}
 
+	if (indio_dev->hwfifo) {
+		ret = indio_dev->hwfifo->set_watermark(indio_dev, val);
+		if (ret)
+			goto out;
+	}
+
 	buffer->low_watermark = val;
 	ret = 0;
 out:
@@ -818,6 +838,16 @@ out:
 	return ret ? ret : len;
 }
 
+ssize_t iio_buffer_hwfifo_read_length(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	const struct iio_hwfifo *hwfifo = indio_dev->hwfifo;
+
+	return sprintf(buf, "%u\n", hwfifo ? hwfifo->length : 0);
+}
+
 static DEVICE_ATTR(length, S_IRUGO | S_IWUSR, iio_buffer_read_length,
 		   iio_buffer_write_length);
 static struct device_attribute dev_attr_length_ro = __ATTR(length,
@@ -826,11 +856,13 @@ static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
 		   iio_buffer_show_enable, iio_buffer_store_enable);
 static DEVICE_ATTR(low_watermark, S_IRUGO | S_IWUSR,
 		   iio_buffer_show_watermark, iio_buffer_store_watermark);
+static DEVICE_ATTR(hwfifo_length, S_IRUGO, iio_buffer_hwfifo_read_length, NULL);
 
 static struct attribute *iio_buffer_attrs[] = {
 	&dev_attr_length.attr,
 	&dev_attr_enable.attr,
 	&dev_attr_low_watermark.attr,
+	&dev_attr_hwfifo_length.attr,
 };
 
 int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 878d861..f64a05f 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -417,6 +417,22 @@ struct iio_buffer_setup_ops {
 };
 
 /**
+ * struct iio_buffer_hwfifo_ops - hardware fifo operations
+ *
+ * @length:		[DRIVER] the hardware fifo length
+ * @set_watermark:	[DRIVER] setups the watermark level
+ * @flush:		[DRIVER] copies data from the hardware buffer to the
+ *		 	device buffer
+ * @watermark_trig:	[DRIVER] an allocated and registered trigger containing
+ *			"watermark" in its name
+ */
+struct iio_hwfifo {
+	int length;
+	int (*set_watermark)(struct iio_dev *, unsigned int);
+	int (*flush)(struct iio_dev *);
+};
+
+/**
  * struct iio_dev - industrial I/O device
  * @id:			[INTERN] used to identify device internally
  * @modes:		[DRIVER] operating modes supported by device
@@ -491,6 +507,7 @@ struct iio_dev {
 	int				groupcounter;
 
 	unsigned long			flags;
+	const struct iio_hwfifo		*hwfifo;
 #if defined(CONFIG_DEBUG_FS)
 	struct dentry			*debugfs_dentry;
 	unsigned			cached_reg_addr;
-- 
1.9.1


  parent reply	other threads:[~2014-12-21  0:44 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-21  0:42 [PATCH v2 00/11] iio: add support for hardware buffers Octavian Purdila
2014-12-21  0:42 ` [PATCH v2 01/11] iio: buffer: fix custom buffer attributes copy Octavian Purdila
2015-01-04 11:25   ` Jonathan Cameron
2015-01-04 11:34     ` Lars-Peter Clausen
2015-01-04 16:11       ` Jonathan Cameron
2014-12-21  0:42 ` [PATCH v2 02/11] iio: buffer: refactor buffer attributes setup Octavian Purdila
2015-01-04 11:31   ` Jonathan Cameron
2015-01-05 10:48     ` Octavian Purdila
2014-12-21  0:42 ` [PATCH v2 03/11] iio: add watermark logic to iio read and poll Octavian Purdila
2015-01-04 15:44   ` Jonathan Cameron
2015-01-25 21:22   ` Hartmut Knaack
2015-01-26  9:40     ` Octavian Purdila
2014-12-21  0:42 ` Octavian Purdila [this message]
2015-01-04 16:07   ` [PATCH v2 04/11] iio: add support for hardware fifo Jonathan Cameron
2015-01-05 11:29     ` Octavian Purdila
2015-02-04 17:08       ` Jonathan Cameron
2015-02-05 21:36         ` Octavian Purdila
2015-02-08 10:53           ` Jonathan Cameron
2015-02-09 13:44             ` Octavian Purdila
2015-01-28 23:46   ` Hartmut Knaack
2015-01-29 11:38     ` Octavian Purdila
2015-01-29 22:49       ` Hartmut Knaack
2015-02-04 17:18         ` Jonathan Cameron
2015-02-04 17:11       ` Jonathan Cameron
2014-12-21  0:42 ` [PATCH v2 05/11] iio: bmc150: refactor slope duration and threshold update Octavian Purdila
2015-01-04 16:21   ` Jonathan Cameron
2015-01-06 18:53     ` Srinivas Pandruvada
2015-01-28  9:22       ` Octavian Purdila
2015-01-28 17:15         ` Srinivas Pandruvada
2014-12-21  0:42 ` [PATCH v2 06/11] iio: bmc150: refactor interrupt enabling Octavian Purdila
2015-01-04 16:27   ` Jonathan Cameron
2015-01-28 10:33     ` Octavian Purdila
2014-12-21  0:42 ` [PATCH v2 07/11] iio: bmc150: exit early if event / trigger state is not changed Octavian Purdila
2015-01-04 16:29   ` Jonathan Cameron
2014-12-21  0:42 ` [PATCH v2 08/11] iio: bmc150: introduce bmc150_accel_interrupt Octavian Purdila
2015-01-04 16:36   ` Jonathan Cameron
2015-01-28 11:09     ` Octavian Purdila
2015-01-28 13:20       ` Jonathan Cameron
2014-12-21  0:42 ` [PATCH v2 09/11] iio: bmc150: introduce bmc150_accel_trigger Octavian Purdila
2015-01-04 16:39   ` Jonathan Cameron
2014-12-21  0:42 ` [PATCH v2 10/11] iio: bmc150: introduce bmc150_accel_event Octavian Purdila
2015-01-04 16:49   ` Jonathan Cameron
2014-12-21  0:42 ` [PATCH v2 11/11] iio: bmc150: add support for hardware fifo Octavian Purdila
2015-01-04 17:08   ` Jonathan Cameron
2015-01-28 19:26     ` Octavian Purdila
2015-02-04 17:16       ` Jonathan Cameron
2015-02-04 20:18         ` Octavian Purdila
2015-02-05 11:20           ` Jonathan Cameron
2015-02-05 20:04             ` Octavian Purdila
2015-02-06 12:19               ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1419122556-8100-5-git-send-email-octavian.purdila@intel.com \
    --to=octavian.purdila@intel.com \
    --cc=linux-iio@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.