* [RFC PATCH 0/7] staging:iio:towards an in kernel push interface
@ 2011-10-26 15:54 Jonathan Cameron
2011-10-26 15:54 ` [PATCH 1/7] staging:iio:buffer drop bpe field Jonathan Cameron
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
Hi All,
Before I say anything else: Note that the interfaces here are a
mess and no intended to reflect what would go on on the inkernel
client side. The current snoop driver is just a hack to test the
push side works. I'll wrap this up and make it look all pretty
once we have pinned the other elements down.
The following is primarily an RFC rather than a firm proposal due
to a few things currently not being there.
1) A decent interface. The snoop driver shows it works but requires
some pretty low level knowledge of what is going on.
2) A lack of any certainty that I haven't broken 90% of more of
the drivers. Hardware buffers for one (sca3000) are going to
be interesting with this.
3) Locking missing all over the place.
4) No means of doing in kernel trigger configuration at the moment
so you'll have have to have a trigger set up BEFORE any driver
tries to insert a buffer for it to feed.
5) Probably want to separate the bits of preenable functions that
deal with setting up scan modes etc from those that run for each
buffer. This is the case with max1363 which uses the update_scan_mode
callback, but the naming doesn't reflect things well.
6) I've only tested it on the max1363 so far with snoop on in_voltage3_raw
and the main buffer set to read in_voltage0_raw and in_voltage2_raw.
A sysfs trigger was used and hammered from a tight loop whilst the
generic_buffer example was used to read from the iio chrdev.
This setup works.
So basically, this 'works', but might eat babies in its current form.
What has changed:
Principally the dataflow has become a little more complex
Before we had
------- -------- ------------ ---------
|Trigger|--->|Device 1| --> |Ring or Fifo| --> |Userspace|
------- -------- ------------ ---------
| -------- ------------ ---------
------->|Device 2| --> |Ring or Fifo| --> |Userspace|
-------- ------------ ---------
Now we have
------- -------- ---------- ------ ---------
|Trigger|->|Device 1| -> |BufferList| -> |R/Fifo| -> |Userspace|
------- -------- ---------- ------ ---------
| |
| ------ | -------------------
----->|Device 2| -> -------> |In Kernel interface|
------ -------------------
So we have inserted a bufferlist. If there is nothing in this
list (initial state) then the poll function is not attached
so the trigger will not cause this device to push to the buffers.
All buffer pushing from the driver is done through
iio_push_to_buffers()
Changes to the buffer list are done by calling iio_buffers_update
which takes a buffer to add or one to remove (or neither).
This function does the following:
1) Tear down current buffering (including detaching the poll function).
2) Add or remove buffers from the list.
3) Setup the Demux. As a change to any buffer can result in a change
to the active scan mask (that may or may not succeed) all demuxes
into the buffers must be updated if they are still attached.
4) Bring up buffinrg (including attaching the pollfunc).
As you can see form the snoop driver, right now we don't really
have an interface, drivers can add buffers by setting up the magic
and inserting them. Whether we need to be nicer than that isn't
immediately clear. Some utility functions would definitely make
things easier to follow though!
Note that the only overhead on a 'normal' driver over what we had
before is a lookup into a list with only one entry + a few pointer
copies. (where normal is without in kernel usage and a scan that
requires no demux).
All comments welcome. I'll be away from a few hours time until
next Monday though so may take me until then to get back to people!
Just thought I'd best show people where things stand before heading
out. All in all it was roughly as fiddly to get this working as
I expected. It's suprising how many decisions turn out to be wrong
when you want to add a diversion for your data...
Jonathan Cameron (7):
staging:iio:buffer drop bpe field.
staging:iio; remove userspace access to bytes per datum.
staging:iio:buffer move setup ops from buffer instance to iio_dev
staging:iio: scrap scan_count and ensure all drivers use
active_scan_mask
staging:iio: make all buffer access pass through the buffer_list
staging:iio: make update buffers available outside iio.
staging:iio:snoop example of rawest level of push interface
drivers/staging/iio/Kconfig | 5 +
drivers/staging/iio/Makefile | 1 +
drivers/staging/iio/accel/adis16201_ring.c | 29 +-
drivers/staging/iio/accel/adis16203_ring.c | 30 +-
drivers/staging/iio/accel/adis16204_ring.c | 28 +-
drivers/staging/iio/accel/adis16209_ring.c | 23 +-
drivers/staging/iio/accel/adis16240_ring.c | 23 +-
drivers/staging/iio/accel/lis3l02dq_ring.c | 44 +-
drivers/staging/iio/accel/sca3000_ring.c | 4 +-
drivers/staging/iio/adc/ad7192.c | 41 +-
drivers/staging/iio/adc/ad7298_ring.c | 48 ++-
drivers/staging/iio/adc/ad7476_ring.c | 37 +-
drivers/staging/iio/adc/ad7606_ring.c | 24 +-
drivers/staging/iio/adc/ad7793.c | 45 +-
drivers/staging/iio/adc/ad7887_ring.c | 42 +-
drivers/staging/iio/adc/ad799x_ring.c | 48 ++-
drivers/staging/iio/adc/max1363_ring.c | 22 +-
drivers/staging/iio/buffer.h | 39 +--
drivers/staging/iio/gyro/adis16260_ring.c | 26 +-
drivers/staging/iio/iio.h | 18 +
drivers/staging/iio/iio_simple_dummy_buffer.c | 29 +-
drivers/staging/iio/iio_snoop.c | 94 ++++
drivers/staging/iio/impedance-analyzer/ad5933.c | 29 +-
drivers/staging/iio/imu/adis16400_ring.c | 24 +-
drivers/staging/iio/industrialio-buffer.c | 574 +++++++++++++----------
drivers/staging/iio/industrialio-core.c | 1 +
drivers/staging/iio/kfifo_buf.c | 2 -
drivers/staging/iio/meter/ade7758_ring.c | 36 +-
drivers/staging/iio/ring_sw.c | 2 -
29 files changed, 835 insertions(+), 533 deletions(-)
create mode 100644 drivers/staging/iio/iio_snoop.c
--
1.7.7
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/7] staging:iio:buffer drop bpe field.
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
@ 2011-10-26 15:54 ` Jonathan Cameron
2011-10-26 15:54 ` [PATCH 2/7] staging:iio; remove userspace access to bytes per datum Jonathan Cameron
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
Has no remaining users.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
drivers/staging/iio/accel/adis16201_ring.c | 1 -
drivers/staging/iio/accel/adis16203_ring.c | 1 -
drivers/staging/iio/accel/adis16204_ring.c | 1 -
drivers/staging/iio/accel/adis16209_ring.c | 1 -
drivers/staging/iio/accel/adis16240_ring.c | 1 -
drivers/staging/iio/accel/lis3l02dq_ring.c | 1 -
drivers/staging/iio/accel/sca3000_ring.c | 2 --
drivers/staging/iio/adc/ad7606_ring.c | 2 --
drivers/staging/iio/buffer.h | 2 --
drivers/staging/iio/gyro/adis16260_ring.c | 1 -
drivers/staging/iio/iio_simple_dummy_buffer.c | 2 --
drivers/staging/iio/imu/adis16400_ring.c | 1 -
12 files changed, 0 insertions(+), 16 deletions(-)
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index dbd8832..3ecfcee 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -115,7 +115,6 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
- ring->bpe = 2;
ring->scan_timestamp = true;
ring->access = &ring_sw_access_funcs;
ring->setup_ops = &adis16201_ring_setup_ops;
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index 838d301..67d9dc9 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -117,7 +117,6 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
}
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
- ring->bpe = 2;
ring->scan_timestamp = true;
ring->access = &ring_sw_access_funcs;
ring->setup_ops = &adis16203_ring_setup_ops;
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 08551bb..53d865e 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -113,7 +113,6 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
- ring->bpe = 2;
ring->scan_timestamp = true;
ring->setup_ops = &adis16204_ring_setup_ops;
ring->owner = THIS_MODULE;
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index bb66364..9f9c31d 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -113,7 +113,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
- ring->bpe = 2;
ring->scan_timestamp = true;
ring->setup_ops = &adis16209_ring_setup_ops;
ring->owner = THIS_MODULE;
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index 34f1e7e..6576e2f 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -110,7 +110,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
- ring->bpe = 2;
ring->scan_timestamp = true;
ring->setup_ops = &adis16240_ring_setup_ops;
ring->owner = THIS_MODULE;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 5c542dd..5f26e53 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -436,7 +436,6 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
indio_dev->buffer = buffer;
/* Effectively select the buffer implementation */
indio_dev->buffer->access = &lis3l02dq_access_funcs;
- buffer->bpe = 2;
buffer->scan_timestamp = true;
buffer->setup_ops = &lis3l02dq_buffer_setup_ops;
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 685ded8..4e1d938 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -146,7 +146,6 @@ static int sca3000_ring_get_bytes_per_datum(struct iio_buffer *r)
}
static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_BYTES_PER_DATUM_ATTR;
static IIO_BUFFER_LENGTH_ATTR;
/**
@@ -243,7 +242,6 @@ static IIO_DEVICE_ATTR(in_accel_scale,
*/
static struct attribute *sca3000_ring_attributes[] = {
&dev_attr_length.attr,
- &dev_attr_bytes_per_datum.attr,
&dev_attr_enable.attr,
&iio_dev_attr_50_percent.dev_attr.attr,
&iio_dev_attr_75_percent.dev_attr.attr,
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index af6780a..203c914 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -136,8 +136,6 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
- indio_dev->buffer->bpe =
- st->chip_info->channels[0].scan_type.storagebits / 8;
indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh,
&ad7606_trigger_handler_th_bh,
0,
diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h
index 5282441..97d59d9 100644
--- a/drivers/staging/iio/buffer.h
+++ b/drivers/staging/iio/buffer.h
@@ -86,7 +86,6 @@ struct iio_buffer_setup_ops {
* @owner: module that owns the buffer (for ref counting)
* @length: [DEVICE] number of datums in buffer
* @bytes_per_datum: [DEVICE] size of individual datum including timestamp
- * @bpe: [DEVICE] size of individual channel value
* @scan_el_attrs: [DRIVER] control of scan elements if that scan mode
* control method is used
* @scan_count: [INTERN] the number of elements in the current scan mode
@@ -103,7 +102,6 @@ struct iio_buffer {
struct module *owner;
int length;
int bytes_per_datum;
- int bpe;
struct attribute_group *scan_el_attrs;
int scan_count;
long *scan_mask;
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 679c151..b18f7e5 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -115,7 +115,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
- ring->bpe = 2;
ring->scan_timestamp = true;
ring->setup_ops = &adis16260_ring_setup_ops;
ring->owner = THIS_MODULE;
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index f0b36d2..2ed4c1c 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -141,8 +141,6 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
/* Tell the core how to access the buffer */
buffer->access = &kfifo_access_funcs;
- /* Number of bytes per element */
- buffer->bpe = 2;
/* Enable timestamps by default */
buffer->scan_timestamp = true;
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index c368245..0c37622 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -185,7 +185,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
indio_dev->buffer = ring;
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
- ring->bpe = 2;
ring->scan_timestamp = true;
ring->setup_ops = &adis16400_ring_setup_ops;
ring->owner = THIS_MODULE;
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/7] staging:iio; remove userspace access to bytes per datum.
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
2011-10-26 15:54 ` [PATCH 1/7] staging:iio:buffer drop bpe field Jonathan Cameron
@ 2011-10-26 15:54 ` Jonathan Cameron
2011-10-26 15:54 ` [PATCH 3/7] staging:iio:buffer move setup ops from buffer instance to iio_dev Jonathan Cameron
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
There are no known reasons why userspace should want this value.
It can be established from the buffer description anyway.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
drivers/staging/iio/buffer.h | 9 ---------
drivers/staging/iio/industrialio-buffer.c | 15 ---------------
drivers/staging/iio/kfifo_buf.c | 2 --
drivers/staging/iio/ring_sw.c | 2 --
4 files changed, 0 insertions(+), 28 deletions(-)
diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h
index 97d59d9..9171735 100644
--- a/drivers/staging/iio/buffer.h
+++ b/drivers/staging/iio/buffer.h
@@ -193,12 +193,6 @@ ssize_t iio_buffer_write_length(struct device *dev,
const char *buf,
size_t len);
/**
- * iio_buffer_read_bytes_per_datum() - attr for number of bytes in whole datum
- **/
-ssize_t iio_buffer_read_bytes_per_datum(struct device *dev,
- struct device_attribute *attr,
- char *buf);
-/**
* iio_buffer_store_enable() - attr to turn the buffer on
**/
ssize_t iio_buffer_store_enable(struct device *dev,
@@ -214,9 +208,6 @@ ssize_t iio_buffer_show_enable(struct device *dev,
#define IIO_BUFFER_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR, \
iio_buffer_read_length, \
iio_buffer_write_length)
-#define IIO_BUFFER_BYTES_PER_DATUM_ATTR \
- DEVICE_ATTR(bytes_per_datum, S_IRUGO | S_IWUSR, \
- iio_buffer_read_bytes_per_datum, NULL)
#define IIO_BUFFER_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \
iio_buffer_show_enable, \
diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c
index 58605b5..e71b515 100644
--- a/drivers/staging/iio/industrialio-buffer.c
+++ b/drivers/staging/iio/industrialio-buffer.c
@@ -408,21 +408,6 @@ ssize_t iio_buffer_write_length(struct device *dev,
}
EXPORT_SYMBOL(iio_buffer_write_length);
-ssize_t iio_buffer_read_bytes_per_datum(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct iio_buffer *buffer = indio_dev->buffer;
-
- if (buffer->access->get_bytes_per_datum)
- return sprintf(buf, "%d\n",
- buffer->access->get_bytes_per_datum(buffer));
-
- return 0;
-}
-EXPORT_SYMBOL(iio_buffer_read_bytes_per_datum);
-
ssize_t iio_buffer_store_enable(struct device *dev,
struct device_attribute *attr,
const char *buf,
diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c
index fd98a0e..fb3b7ae 100644
--- a/drivers/staging/iio/kfifo_buf.c
+++ b/drivers/staging/iio/kfifo_buf.c
@@ -75,12 +75,10 @@ static inline void __iio_init_kfifo(struct iio_kfifo *kf)
}
static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_BYTES_PER_DATUM_ATTR;
static IIO_BUFFER_LENGTH_ATTR;
static struct attribute *iio_kfifo_attributes[] = {
&dev_attr_length.attr,
- &dev_attr_bytes_per_datum.attr,
&dev_attr_enable.attr,
NULL,
};
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 66a34ad..98fe819 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -393,13 +393,11 @@ static int iio_mark_update_needed_sw_rb(struct iio_buffer *r)
}
static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_BYTES_PER_DATUM_ATTR;
static IIO_BUFFER_LENGTH_ATTR;
/* Standard set of ring buffer attributes */
static struct attribute *iio_ring_attributes[] = {
&dev_attr_length.attr,
- &dev_attr_bytes_per_datum.attr,
&dev_attr_enable.attr,
NULL,
};
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/7] staging:iio:buffer move setup ops from buffer instance to iio_dev
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
2011-10-26 15:54 ` [PATCH 1/7] staging:iio:buffer drop bpe field Jonathan Cameron
2011-10-26 15:54 ` [PATCH 2/7] staging:iio; remove userspace access to bytes per datum Jonathan Cameron
@ 2011-10-26 15:54 ` Jonathan Cameron
2011-10-26 15:54 ` [PATCH 4/7] staging:iio: scrap scan_count and ensure all drivers use active_scan_mask Jonathan Cameron
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
These callbacks should not be buffer instance specific.
Hence move them out of the buffer.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
drivers/staging/iio/accel/adis16201_ring.c | 2 +-
drivers/staging/iio/accel/adis16203_ring.c | 2 +-
drivers/staging/iio/accel/adis16204_ring.c | 2 +-
drivers/staging/iio/accel/adis16209_ring.c | 2 +-
drivers/staging/iio/accel/adis16240_ring.c | 2 +-
drivers/staging/iio/accel/lis3l02dq_ring.c | 2 +-
drivers/staging/iio/accel/sca3000_ring.c | 2 +-
drivers/staging/iio/adc/ad7192.c | 2 +-
drivers/staging/iio/adc/ad7298_ring.c | 2 +-
drivers/staging/iio/adc/ad7476_ring.c | 2 +-
drivers/staging/iio/adc/ad7606_ring.c | 2 +-
drivers/staging/iio/adc/ad7793.c | 2 +-
drivers/staging/iio/adc/ad7887_ring.c | 2 +-
drivers/staging/iio/adc/ad799x_ring.c | 2 +-
drivers/staging/iio/adc/max1363_ring.c | 2 +-
drivers/staging/iio/buffer.h | 16 ----------------
drivers/staging/iio/gyro/adis16260_ring.c | 2 +-
drivers/staging/iio/iio.h | 16 ++++++++++++++++
drivers/staging/iio/iio_simple_dummy_buffer.c | 2 +-
drivers/staging/iio/impedance-analyzer/ad5933.c | 2 +-
drivers/staging/iio/imu/adis16400_ring.c | 2 +-
drivers/staging/iio/industrialio-buffer.c | 20 ++++++++++----------
drivers/staging/iio/meter/ade7758_ring.c | 2 +-
23 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 3ecfcee..787a719 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -117,7 +117,7 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
ring->scan_timestamp = true;
ring->access = &ring_sw_access_funcs;
- ring->setup_ops = &adis16201_ring_setup_ops;
+ indio_dev->setup_ops = &adis16201_ring_setup_ops;
ring->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index 67d9dc9..55020fb 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -119,7 +119,7 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
ring->scan_timestamp = true;
ring->access = &ring_sw_access_funcs;
- ring->setup_ops = &adis16203_ring_setup_ops;
+ indio_dev->setup_ops = &adis16203_ring_setup_ops;
ring->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 53d865e..33f59fb 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -114,7 +114,7 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
- ring->setup_ops = &adis16204_ring_setup_ops;
+ indio_dev->setup_ops = &adis16204_ring_setup_ops;
ring->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 9f9c31d..37f0f7f 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -114,7 +114,7 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
- ring->setup_ops = &adis16209_ring_setup_ops;
+ indio_dev->setup_ops = &adis16209_ring_setup_ops;
ring->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index 6576e2f..08e8625 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -111,7 +111,7 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
- ring->setup_ops = &adis16240_ring_setup_ops;
+ indio_dev->setup_ops = &adis16240_ring_setup_ops;
ring->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 5f26e53..410c6d6 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -438,7 +438,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
indio_dev->buffer->access = &lis3l02dq_access_funcs;
buffer->scan_timestamp = true;
- buffer->setup_ops = &lis3l02dq_buffer_setup_ops;
+ indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
buffer->owner = THIS_MODULE;
/* Functions are NULL as we set handler below */
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 4e1d938..6a27a95 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -348,7 +348,7 @@ static const struct iio_buffer_setup_ops sca3000_ring_setup_ops = {
void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
{
- indio_dev->buffer->setup_ops = &sca3000_ring_setup_ops;
+ indio_dev->setup_ops = &sca3000_ring_setup_ops;
}
/**
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 1dd0f9f..f706c90 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -592,7 +592,7 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev)
}
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad7192_ring_setup_ops;
+ indio_dev->setup_ops = &ad7192_ring_setup_ops;
/* Flag that polled ring buffering is possible */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 192328e..611e212 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -174,7 +174,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
}
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad7298_ring_setup_ops;
+ indio_dev->setup_ops = &ad7298_ring_setup_ops;
indio_dev->buffer->scan_timestamp = true;
/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index 0961887..2dad7f8 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -137,7 +137,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
}
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad7476_ring_setup_ops;
+ indio_dev->setup_ops = &ad7476_ring_setup_ops;
indio_dev->buffer->scan_timestamp = true;
/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index 203c914..f682af6 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -150,7 +150,7 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad7606_ring_setup_ops;
+ indio_dev->setup_ops = &ad7606_ring_setup_ops;
indio_dev->buffer->scan_timestamp = true ;
INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index cbefa22..0220aea 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -458,7 +458,7 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev)
}
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad7793_ring_setup_ops;
+ indio_dev->setup_ops = &ad7793_ring_setup_ops;
/* Flag that polled ring buffering is possible */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index fbe21b5..fee338c 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -176,7 +176,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
goto error_deallocate_sw_rb;
}
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad7887_ring_setup_ops;
+ indio_dev->setup_ops = &ad7887_ring_setup_ops;
/* Flag that polled ring buffering is possible */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index b215a1f..50c1216 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -183,7 +183,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
}
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad799x_buf_setup_ops;
+ indio_dev->setup_ops = &ad799x_buf_setup_ops;
indio_dev->buffer->scan_timestamp = true;
/* Flag that polled ring buffering is possible */
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 19977a6..3a38a26 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -155,7 +155,7 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &max1363_ring_setup_ops;
+ indio_dev->setup_ops = &max1363_ring_setup_ops;
/* Flag that polled ring buffering is possible */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h
index 9171735..58c7571 100644
--- a/drivers/staging/iio/buffer.h
+++ b/drivers/staging/iio/buffer.h
@@ -66,21 +66,6 @@ struct iio_buffer_access_funcs {
};
/**
- * struct iio_buffer_setup_ops - buffer setup related callbacks
- * @preenable: [DRIVER] function to run prior to marking buffer enabled
- * @postenable: [DRIVER] function to run after marking buffer enabled
- * @predisable: [DRIVER] function to run prior to marking buffer
- * disabled
- * @postdisable: [DRIVER] function to run after marking buffer disabled
- */
-struct iio_buffer_setup_ops {
- int (*preenable)(struct iio_dev *);
- int (*postenable)(struct iio_dev *);
- int (*predisable)(struct iio_dev *);
- int (*postdisable)(struct iio_dev *);
-};
-
-/**
* struct iio_buffer - general buffer structure
* @indio_dev: industrial I/O device structure
* @owner: module that owns the buffer (for ref counting)
@@ -108,7 +93,6 @@ struct iio_buffer {
bool scan_timestamp;
unsigned scan_index_timestamp;
const struct iio_buffer_access_funcs *access;
- const struct iio_buffer_setup_ops *setup_ops;
struct list_head scan_el_dev_attr_list;
struct attribute_group scan_el_group;
wait_queue_head_t pollq;
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index b18f7e5..675b05d 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -116,7 +116,7 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
- ring->setup_ops = &adis16260_ring_setup_ops;
+ indio_dev->setup_ops = &adis16260_ring_setup_ops;
ring->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index e30d33d..bd29412 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -270,6 +270,21 @@ struct iio_info {
};
/**
+ * struct iio_buffer_setup_ops - buffer setup related callbacks
+ * @preenable: [DRIVER] function to run prior to marking buffer enabled
+ * @postenable: [DRIVER] function to run after marking buffer enabled
+ * @predisable: [DRIVER] function to run prior to marking buffer
+ * disabled
+ * @postdisable: [DRIVER] function to run after marking buffer disabled
+ */
+struct iio_buffer_setup_ops {
+ int (*preenable)(struct iio_dev *);
+ int (*postenable)(struct iio_dev *);
+ int (*predisable)(struct iio_dev *);
+ int (*postdisable)(struct iio_dev *);
+};
+
+/**
* struct iio_dev - industrial I/O device
* @id: [INTERN] used to identify device internally
* @modes: [DRIVER] operating modes supported by device
@@ -322,6 +337,7 @@ struct iio_dev {
struct attribute_group chan_attr_group;
const char *name;
const struct iio_info *info;
+ const struct iio_buffer_setup_ops *setup_ops;
struct cdev chrdev;
#define IIO_MAX_GROUPS 6
const struct attribute_group *groups[IIO_MAX_GROUPS + 1];
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index 2ed4c1c..c572f8b 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -148,7 +148,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
* Tell the core what device type specific functions should
* be run on either side of buffer capture enable / disable.
*/
- buffer->setup_ops = &iio_simple_dummy_buffer_setup_ops;
+ indio_dev->setup_ops = &iio_simple_dummy_buffer_setup_ops;
buffer->owner = THIS_MODULE;
/*
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 56c89af..2576fc2 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -611,7 +611,7 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
indio_dev->buffer->access = &ring_sw_access_funcs;
/* Ring buffer functions - here trigger setup related */
- indio_dev->buffer->setup_ops = &ad5933_ring_setup_ops;
+ indio_dev->setup_ops = &ad5933_ring_setup_ops;
indio_dev->modes |= INDIO_BUFFER_HARDWARE;
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 0c37622..aaf53f6 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -186,7 +186,7 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
ring->access = &ring_sw_access_funcs;
ring->scan_timestamp = true;
- ring->setup_ops = &adis16400_ring_setup_ops;
+ indio_dev->setup_ops = &adis16400_ring_setup_ops;
ring->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c
index e71b515..5f9ed47 100644
--- a/drivers/staging/iio/industrialio-buffer.c
+++ b/drivers/staging/iio/industrialio-buffer.c
@@ -428,8 +428,8 @@ ssize_t iio_buffer_store_enable(struct device *dev,
goto done;
}
if (requested_state) {
- if (buffer->setup_ops->preenable) {
- ret = buffer->setup_ops->preenable(indio_dev);
+ if (indio_dev->setup_ops->preenable) {
+ ret = indio_dev->setup_ops->preenable(indio_dev);
if (ret) {
printk(KERN_ERR
"Buffer not started:"
@@ -466,8 +466,8 @@ ssize_t iio_buffer_store_enable(struct device *dev,
goto error_ret;
}
- if (buffer->setup_ops->postenable) {
- ret = buffer->setup_ops->postenable(indio_dev);
+ if (indio_dev->setup_ops->postenable) {
+ ret = indio_dev->setup_ops->postenable(indio_dev);
if (ret) {
printk(KERN_INFO
"Buffer not started:"
@@ -475,23 +475,23 @@ ssize_t iio_buffer_store_enable(struct device *dev,
if (buffer->access->unmark_in_use)
buffer->access->unmark_in_use(buffer);
indio_dev->currentmode = previous_mode;
- if (buffer->setup_ops->postdisable)
- buffer->setup_ops->
+ if (indio_dev->setup_ops->postdisable)
+ indio_dev->setup_ops->
postdisable(indio_dev);
goto error_ret;
}
}
} else {
- if (buffer->setup_ops->predisable) {
- ret = buffer->setup_ops->predisable(indio_dev);
+ if (indio_dev->setup_ops->predisable) {
+ ret = indio_dev->setup_ops->predisable(indio_dev);
if (ret)
goto error_ret;
}
if (buffer->access->unmark_in_use)
buffer->access->unmark_in_use(buffer);
indio_dev->currentmode = INDIO_DIRECT_MODE;
- if (buffer->setup_ops->postdisable) {
- ret = buffer->setup_ops->postdisable(indio_dev);
+ if (indio_dev->setup_ops->postdisable) {
+ ret = indio_dev->setup_ops->postdisable(indio_dev);
if (ret)
goto error_ret;
}
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 99ade65..25df982 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -144,7 +144,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
/* Effectively select the ring buffer implementation */
indio_dev->buffer->access = &ring_sw_access_funcs;
- indio_dev->buffer->setup_ops = &ade7758_ring_setup_ops;
+ indio_dev->setup_ops = &ade7758_ring_setup_ops;
indio_dev->buffer->owner = THIS_MODULE;
indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/7] staging:iio: scrap scan_count and ensure all drivers use active_scan_mask
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
` (2 preceding siblings ...)
2011-10-26 15:54 ` [PATCH 3/7] staging:iio:buffer move setup ops from buffer instance to iio_dev Jonathan Cameron
@ 2011-10-26 15:54 ` Jonathan Cameron
2011-10-26 15:54 ` [PATCH 5/7] staging:iio: make all buffer access pass through the buffer_list Jonathan Cameron
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
Obviously drivers should only use this for pushing to buffers.
They need buffer->scan_mask for pulling from them post demux.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
drivers/staging/iio/accel/adis16201_ring.c | 10 +++++-----
drivers/staging/iio/accel/adis16203_ring.c | 10 +++++-----
drivers/staging/iio/accel/adis16204_ring.c | 10 +++++-----
drivers/staging/iio/accel/adis16209_ring.c | 5 +++--
drivers/staging/iio/accel/adis16240_ring.c | 5 +++--
drivers/staging/iio/accel/lis3l02dq_ring.c | 23 +++++++++++++----------
drivers/staging/iio/adc/ad7192.c | 9 +++++----
drivers/staging/iio/adc/ad7298_ring.c | 12 +++++++-----
drivers/staging/iio/adc/ad7476_ring.c | 3 ++-
drivers/staging/iio/adc/ad7793.c | 11 ++++++-----
drivers/staging/iio/adc/ad7887_ring.c | 8 +++++---
drivers/staging/iio/adc/ad799x_ring.c | 12 +++++++-----
drivers/staging/iio/buffer.h | 2 --
drivers/staging/iio/gyro/adis16260_ring.c | 5 +++--
drivers/staging/iio/impedance-analyzer/ad5933.c | 14 ++++++++------
drivers/staging/iio/imu/adis16400_ring.c | 19 +++++++++++--------
drivers/staging/iio/meter/ade7758_ring.c | 6 +++---
17 files changed, 91 insertions(+), 73 deletions(-)
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 787a719..504773d 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -73,11 +73,11 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
return -ENOMEM;
}
- if (ring->scan_count)
- if (adis16201_read_ring_data(indio_dev, st->rx) >= 0)
- for (; i < ring->scan_count; i++)
- data[i] = be16_to_cpup(
- (__be16 *)&(st->rx[i*2]));
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)
+ && adis16201_read_ring_data(indio_dev, st->rx) >= 0)
+ for (; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++)
+ data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp)
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index 55020fb..dfa9cb0 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -73,11 +73,11 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
return -ENOMEM;
}
- if (ring->scan_count)
- if (adis16203_read_ring_data(&indio_dev->dev, st->rx) >= 0)
- for (; i < ring->scan_count; i++)
- data[i] = be16_to_cpup(
- (__be16 *)&(st->rx[i*2]));
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
+ adis16203_read_ring_data(&indio_dev->dev, st->rx) >= 0)
+ for (; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++)
+ data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp)
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 33f59fb..8559cb5 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -70,11 +70,11 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
return -ENOMEM;
}
- if (ring->scan_count)
- if (adis16204_read_ring_data(&indio_dev->dev, st->rx) >= 0)
- for (; i < ring->scan_count; i++)
- data[i] = be16_to_cpup(
- (__be16 *)&(st->rx[i*2]));
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
+ adis16204_read_ring_data(&indio_dev->dev, st->rx) >= 0)
+ for (; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++)
+ data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp)
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 37f0f7f..971aff6 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -71,9 +71,10 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
return -ENOMEM;
}
- if (ring->scan_count &&
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
adis16209_read_ring_data(&indio_dev->dev, st->rx) >= 0)
- for (; i < ring->scan_count; i++)
+ for (; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index 08e8625..e4ede74 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -68,9 +68,10 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
return -ENOMEM;
}
- if (ring->scan_count &&
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
adis16240_read_ring_data(&indio_dev->dev, st->rx) >= 0)
- for (; i < ring->scan_count; i++)
+ for (; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 410c6d6..8a1d5fe 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -86,13 +86,13 @@ static const u8 read_all_tx_array[] = {
**/
static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
{
- struct iio_buffer *buffer = indio_dev->buffer;
struct lis3l02dq_state *st = iio_priv(indio_dev);
struct spi_transfer *xfers;
struct spi_message msg;
int ret, i, j = 0;
- xfers = kzalloc((buffer->scan_count) * 2
+ xfers = kzalloc(bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) * 2
* sizeof(*xfers), GFP_KERNEL);
if (!xfers)
return -ENOMEM;
@@ -100,7 +100,7 @@ static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
mutex_lock(&st->buf_lock);
for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++)
- if (test_bit(i, buffer->scan_mask)) {
+ if (test_bit(i, indio_dev->active_scan_mask)) {
/* lower byte */
xfers[j].tx_buf = st->tx + 2*j;
st->tx[2*j] = read_all_tx_array[i*4];
@@ -128,7 +128,8 @@ static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
* values in alternate bytes
*/
spi_message_init(&msg);
- for (j = 0; j < buffer->scan_count * 2; j++)
+ for (j = 0; j < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) * 2; j++)
spi_message_add_tail(&xfers[j], &msg);
ret = spi_sync(st->us, &msg);
@@ -144,14 +145,16 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,
int ret, i;
u8 *rx_array ;
s16 *data = (s16 *)buf;
+ int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
- rx_array = kzalloc(4 * (indio_dev->buffer->scan_count), GFP_KERNEL);
+ rx_array = kzalloc(4 * scan_count, GFP_KERNEL);
if (rx_array == NULL)
return -ENOMEM;
ret = lis3l02dq_read_all(indio_dev, rx_array);
if (ret < 0)
return ret;
- for (i = 0; i < indio_dev->buffer->scan_count; i++)
+ for (i = 0; i < scan_count; i++)
data[i] = combine_8_to_16(rx_array[i*4+1],
rx_array[i*4+3]);
kfree(rx_array);
@@ -174,7 +177,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
return -ENOMEM;
}
- if (buffer->scan_count)
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
len = lis3l02dq_get_buffer_element(indio_dev, data);
/* Guaranteed to be aligned with 8 byte boundary */
@@ -362,17 +365,17 @@ static int lis3l02dq_buffer_postenable(struct iio_dev *indio_dev)
if (ret)
goto error_ret;
- if (iio_scan_mask_query(indio_dev->buffer, 0)) {
+ if (test_bit(0, indio_dev->active_scan_mask)) {
t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
oneenabled = true;
} else
t &= ~LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
- if (iio_scan_mask_query(indio_dev->buffer, 1)) {
+ if (test_bit(1, indio_dev->active_scan_mask)) {
t |= LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
oneenabled = true;
} else
t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
- if (iio_scan_mask_query(indio_dev->buffer, 2)) {
+ if (test_bit(2, indio_dev->active_scan_mask)) {
t |= LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
oneenabled = true;
} else
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index f706c90..28266d4 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -479,12 +479,13 @@ static int ad7192_ring_preenable(struct iio_dev *indio_dev)
size_t d_size;
unsigned channel;
- if (!ring->scan_count)
+ if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
+ channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength);
- d_size = ring->scan_count *
+ d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) *
indio_dev->channels[0].scan_type.storagebits / 8;
if (ring->scan_timestamp) {
@@ -544,7 +545,7 @@ static irqreturn_t ad7192_trigger_handler(int irq, void *p)
s64 dat64[2];
s32 *dat32 = (s32 *)dat64;
- if (ring->scan_count)
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
__ad7192_read_reg(st, 1, 1, AD7192_REG_DATA,
dat32,
indio_dev->channels[0].scan_type.realbits/8);
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 611e212..5695eb2 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -61,8 +61,9 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
size_t d_size;
int i, m;
unsigned short command;
-
- d_size = ring->scan_count * (AD7298_STORAGE_BITS / 8);
+ int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
+ d_size = scan_count * (AD7298_STORAGE_BITS / 8);
if (ring->scan_timestamp) {
d_size += sizeof(s64);
@@ -79,7 +80,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
command = AD7298_WRITE | st->ext_ref;
for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1)
- if (test_bit(i, ring->scan_mask))
+ if (test_bit(i, indio_dev->active_scan_mask))
command |= m;
st->tx_buf[0] = cpu_to_be16(command);
@@ -96,7 +97,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev)
spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
- for (i = 0; i < ring->scan_count; i++) {
+ for (i = 0; i < scan_count; i++) {
st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i];
st->ring_xfer[i + 2].len = 2;
st->ring_xfer[i + 2].cs_change = 1;
@@ -134,7 +135,8 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
&time_ns, sizeof(time_ns));
}
- for (i = 0; i < ring->scan_count; i++)
+ for (i = 0; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++)
buf[i] = be16_to_cpu(st->rx_buf[i]);
indio_dev->buffer->access->store_to(ring, (u8 *)buf, time_ns);
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index 2dad7f8..ff0656a 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -56,7 +56,8 @@ static int ad7476_ring_preenable(struct iio_dev *indio_dev)
struct ad7476_state *st = iio_priv(indio_dev);
struct iio_buffer *ring = indio_dev->buffer;
- st->d_size = ring->scan_count *
+ st->d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) *
st->chip_info->channel[0].scan_type.storagebits / 8;
if (ring->scan_timestamp) {
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index 0220aea..dfc904c 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -341,14 +341,15 @@ static int ad7793_ring_preenable(struct iio_dev *indio_dev)
size_t d_size;
unsigned channel;
- if (!ring->scan_count)
+ if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- channel = find_first_bit(ring->scan_mask,
+ channel = find_first_bit(indio_dev->active_scan_mask,
indio_dev->masklength);
- d_size = ring->scan_count *
- indio_dev->channels[0].scan_type.storagebits / 8;
+ d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) *
+ indio_dev->channels[0].scan_type.storagebits / 8;
if (ring->scan_timestamp) {
d_size += sizeof(s64);
@@ -410,7 +411,7 @@ static irqreturn_t ad7793_trigger_handler(int irq, void *p)
s64 dat64[2];
s32 *dat32 = (s32 *)dat64;
- if (ring->scan_count)
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
__ad7793_read_reg(st, 1, 1, AD7793_REG_DATA,
dat32,
indio_dev->channels[0].scan_type.realbits/8);
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index fee338c..f53a663 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -65,7 +65,8 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev)
struct ad7887_state *st = iio_priv(indio_dev);
struct iio_buffer *ring = indio_dev->buffer;
- st->d_size = ring->scan_count *
+ st->d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) *
st->chip_info->channel[0].scan_type.storagebits / 8;
if (ring->scan_timestamp) {
@@ -80,7 +81,7 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev)
set_bytes_per_datum(indio_dev->buffer, st->d_size);
/* We know this is a single long so can 'cheat' */
- switch (*ring->scan_mask) {
+ switch (*indio_dev->active_scan_mask) {
case (1 << 0):
st->ring_msg = &st->msg[AD7887_CH0];
break;
@@ -121,7 +122,8 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
__u8 *buf;
int b_sent;
- unsigned int bytes = ring->scan_count *
+ unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) *
st->chip_info->channel[0].scan_type.storagebits / 8;
buf = kzalloc(st->d_size, GFP_KERNEL);
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 50c1216..12a43db 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -71,9 +71,10 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
*/
if (st->id == ad7997 || st->id == ad7998)
- ad7997_8_set_scan_mode(st, *ring->scan_mask);
+ ad7997_8_set_scan_mode(st, *indio_dev->active_scan_mask);
- st->d_size = ring->scan_count * 2;
+ st->d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) * 2;
if (ring->scan_timestamp) {
st->d_size += sizeof(s64);
@@ -115,12 +116,12 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
case ad7991:
case ad7995:
case ad7999:
- cmd = st->config | (*ring->scan_mask << AD799X_CHANNEL_SHIFT);
+ cmd = st->config | (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT);
break;
case ad7992:
case ad7993:
case ad7994:
- cmd = (*ring->scan_mask << AD799X_CHANNEL_SHIFT) |
+ cmd = (*indio_dev->active_scan_mask << AD799X_CHANNEL_SHIFT) |
AD7998_CONV_RES_REG;
break;
case ad7997:
@@ -132,7 +133,8 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
}
b_sent = i2c_smbus_read_i2c_block_data(st->client,
- cmd, ring->scan_count * 2, rxbuf);
+ cmd, bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) * 2, rxbuf);
if (b_sent < 0)
goto done;
diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h
index 58c7571..7fc0894 100644
--- a/drivers/staging/iio/buffer.h
+++ b/drivers/staging/iio/buffer.h
@@ -73,7 +73,6 @@ struct iio_buffer_access_funcs {
* @bytes_per_datum: [DEVICE] size of individual datum including timestamp
* @scan_el_attrs: [DRIVER] control of scan elements if that scan mode
* control method is used
- * @scan_count: [INTERN] the number of elements in the current scan mode
* @scan_mask: [INTERN] bitmask used in masking scan mode elements
* @scan_timestamp: [INTERN] does the scan mode include a timestamp
* @access: [DRIVER] buffer access functions associated with the
@@ -88,7 +87,6 @@ struct iio_buffer {
int length;
int bytes_per_datum;
struct attribute_group *scan_el_attrs;
- int scan_count;
long *scan_mask;
bool scan_timestamp;
unsigned scan_index_timestamp;
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 675b05d..6a9b5db4 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -73,9 +73,10 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
return -ENOMEM;
}
- if (ring->scan_count &&
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
adis16260_read_ring_data(&indio_dev->dev, st->rx) >= 0)
- for (; i < ring->scan_count; i++)
+ for (; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 2576fc2..8da86b7 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -537,14 +537,14 @@ static const struct iio_info ad5933_info = {
static int ad5933_ring_preenable(struct iio_dev *indio_dev)
{
struct ad5933_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
size_t d_size;
int ret;
- if (!ring->scan_count)
+ if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- d_size = ring->scan_count *
+ d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) *
ad5933_channels[1].scan_type.storagebits / 8;
if (indio_dev->buffer->access->set_bytes_per_datum)
@@ -640,12 +640,14 @@ static void ad5933_work(struct work_struct *work)
ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status);
if (status & AD5933_STAT_DATA_VALID) {
+ int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
ad5933_i2c_read(st->client,
- test_bit(1, ring->scan_mask) ?
+ test_bit(1, indio_dev->active_scan_mask) ?
AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA,
- ring->scan_count * 2, (u8 *)buf);
+ scan_count * 2, (u8 *)buf);
- if (ring->scan_count == 2) {
+ if (scan_count == 2) {
buf[0] = be16_to_cpu(buf[0]);
buf[1] = be16_to_cpu(buf[1]);
} else {
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index aaf53f6..9506e05 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -78,14 +78,16 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx)
struct spi_message msg;
int i, j = 0, ret;
struct spi_transfer *xfers;
+ int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
- xfers = kzalloc(sizeof(*xfers)*indio_dev->buffer->scan_count + 1,
+ xfers = kzalloc(sizeof(*xfers)*(scan_count + 1),
GFP_KERNEL);
if (xfers == NULL)
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
- if (test_bit(i, indio_dev->buffer->scan_mask)) {
+ if (test_bit(i, indio_dev->active_scan_mask)) {
xfers[j].tx_buf = &read_all_tx_array[i];
xfers[j].bits_per_word = 16;
xfers[j].len = 2;
@@ -96,7 +98,7 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx)
xfers[j].len = 2;
spi_message_init(&msg);
- for (j = 0; j < indio_dev->buffer->scan_count + 1; j++)
+ for (j = 0; j < scan_count + 1; j++)
spi_message_add_tail(&xfers[j], &msg);
ret = spi_sync(st->us, &msg);
@@ -118,26 +120,27 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
s16 *data;
size_t datasize = ring->access->get_bytes_per_datum(ring);
/* Asumption that long is enough for maximum channels */
- unsigned long mask = *ring->scan_mask;
-
+ unsigned long mask = *indio_dev->active_scan_mask;
+ int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
dev_err(&st->us->dev, "memory alloc failed in ring bh");
return -ENOMEM;
}
- if (ring->scan_count) {
+ if (scan_count) {
if (st->variant->flags & ADIS16400_NO_BURST) {
ret = adis16350_spi_read_all(&indio_dev->dev, st->rx);
if (ret < 0)
goto err;
- for (; i < ring->scan_count; i++)
+ for (; i < scan_count; i++)
data[i] = *(s16 *)(st->rx + i*2);
} else {
ret = adis16400_spi_read_burst(&indio_dev->dev, st->rx);
if (ret < 0)
goto err;
- for (; i < indio_dev->buffer->scan_count; i++) {
+ for (; i < scan_count; i++) {
j = __ffs(mask);
mask &= ~(1 << j);
data[i] = be16_to_cpup(
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 25df982..893d4b4 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -66,7 +66,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
s64 dat64[2];
u32 *dat32 = (u32 *)dat64;
- if (ring->scan_count)
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
if (ade7758_spi_read_burst(&indio_dev->dev) >= 0)
*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
@@ -95,10 +95,10 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
size_t d_size;
unsigned channel;
- if (!ring->scan_count)
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- channel = find_first_bit(ring->scan_mask, indio_dev->masklength);
+ channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength);
d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8;
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/7] staging:iio: make all buffer access pass through the buffer_list
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
` (3 preceding siblings ...)
2011-10-26 15:54 ` [PATCH 4/7] staging:iio: scrap scan_count and ensure all drivers use active_scan_mask Jonathan Cameron
@ 2011-10-26 15:54 ` Jonathan Cameron
2011-10-26 15:54 ` [PATCH 6/7] staging:iio: make update buffers available outside iio Jonathan Cameron
2011-10-26 15:54 ` [PATCH 7/7] staging:iio:snoop example of rawest level of push interface Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
Crucial step in allowing multiple interfaces.
Main stages:
1) Ensure no trigger_handler touches the buffers directly.
They should only care about active_scan_mask and scan_timestamp
in indio_dev.
2) Ensure all setup ops for the buffers act on the general mode
and the individual buffers in a consistent fashion.
There are almost certainly better ways of doing some of this
and I could probably have broken the set up more. That will
have to wait for round 3.
---
drivers/staging/iio/accel/adis16201_ring.c | 16 +-
drivers/staging/iio/accel/adis16203_ring.c | 17 +-
drivers/staging/iio/accel/adis16204_ring.c | 15 +-
drivers/staging/iio/accel/adis16209_ring.c | 15 +-
drivers/staging/iio/accel/adis16240_ring.c | 15 +-
drivers/staging/iio/accel/lis3l02dq_ring.c | 18 +-
drivers/staging/iio/adc/ad7192.c | 36 +-
drivers/staging/iio/adc/ad7298_ring.c | 42 ++-
drivers/staging/iio/adc/ad7476_ring.c | 32 +-
drivers/staging/iio/adc/ad7606_ring.c | 20 +-
drivers/staging/iio/adc/ad7793.c | 40 +-
drivers/staging/iio/adc/ad7887_ring.c | 32 +-
drivers/staging/iio/adc/ad799x_ring.c | 34 +-
drivers/staging/iio/adc/max1363_ring.c | 20 +-
drivers/staging/iio/buffer.h | 6 +
drivers/staging/iio/gyro/adis16260_ring.c | 18 +-
drivers/staging/iio/iio.h | 2 +
drivers/staging/iio/iio_simple_dummy_buffer.c | 25 +-
drivers/staging/iio/impedance-analyzer/ad5933.c | 17 +-
drivers/staging/iio/imu/adis16400_ring.c | 2 +-
drivers/staging/iio/industrialio-buffer.c | 568 ++++++++++++++---------
drivers/staging/iio/industrialio-core.c | 1 +
drivers/staging/iio/meter/ade7758_ring.c | 30 +-
23 files changed, 622 insertions(+), 399 deletions(-)
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 504773d..897b97f 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -61,11 +61,19 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16201_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
- size_t datasize = ring->access->get_bytes_per_datum(ring);
+ size_t datasize;
+
+ /* This is available for them demux unit */
+ datasize = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+ if (indio_dev->scan_timestamp) {
+ if (datasize % sizeof(s64))
+ datasize += sizeof(s64) - datasize % sizeof(s64);
+ datasize += sizeof(s64);
+ }
data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
@@ -80,10 +88,10 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index dfa9cb0..21e349aa 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -61,11 +61,18 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16203_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
- size_t datasize = ring->access->get_bytes_per_datum(ring);
+ size_t datasize;
+
+ datasize = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+ if (indio_dev->scan_timestamp) {
+ if (datasize % sizeof(s64))
+ datasize += sizeof(s64) - datasize % sizeof(s64);
+ datasize += sizeof(s64);
+ }
data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
@@ -80,12 +87,10 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring,
- (u8 *)data,
- pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 8559cb5..322d0c1 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -59,10 +59,17 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16204_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
- size_t datasize = ring->access->get_bytes_per_datum(ring);
+ size_t datasize;
+
+ datasize = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+ if (indio_dev->scan_timestamp) {
+ if (datasize % sizeof(s64))
+ datasize += sizeof(s64) - datasize % sizeof(s64);
+ datasize += sizeof(s64);
+ }
data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
@@ -77,10 +84,10 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 971aff6..7731d42 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -59,12 +59,17 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16209_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
-
int i = 0;
s16 *data;
- size_t datasize = ring->access->get_bytes_per_datum(ring);
+ size_t datasize;
+ datasize = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+ if (indio_dev->scan_timestamp) {
+ if (datasize % sizeof(s64))
+ datasize += sizeof(s64) - datasize % sizeof(s64);
+ datasize += sizeof(s64);
+ }
data = kmalloc(datasize , GFP_KERNEL);
if (data == NULL) {
dev_err(&st->us->dev, "memory alloc failed in ring bh");
@@ -78,10 +83,10 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index e4ede74..ccbcace 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -56,12 +56,17 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16240_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
-
int i = 0;
s16 *data;
- size_t datasize = ring->access->get_bytes_per_datum(ring);
+ size_t datasize;
+ datasize = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+ if (indio_dev->scan_timestamp) {
+ if (datasize % sizeof(s64))
+ datasize += sizeof(s64) - datasize % sizeof(s64);
+ datasize += sizeof(s64);
+ }
data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
dev_err(&st->us->dev, "memory alloc failed in ring bh");
@@ -75,10 +80,10 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 8a1d5fe..ed75ed4 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -166,11 +166,19 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *buffer = indio_dev->buffer;
int len = 0;
- size_t datasize = buffer->access->get_bytes_per_datum(buffer);
- char *data = kmalloc(datasize, GFP_KERNEL);
+ size_t datasize;
+ char *data;
+ datasize = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+ if (indio_dev->scan_timestamp) {
+ if (datasize % sizeof(s64))
+ datasize += sizeof(s64) - datasize % sizeof(s64);
+ datasize += sizeof(s64);
+ }
+
+ data = kmalloc(datasize, GFP_KERNEL);
if (data == NULL) {
dev_err(indio_dev->dev.parent,
"memory alloc failed in buffer bh");
@@ -181,11 +189,11 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
len = lis3l02dq_get_buffer_element(indio_dev, data);
/* Guaranteed to be aligned with 8 byte boundary */
- if (buffer->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*(s64 *)(((phys_addr_t)data + len
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
= pf->timestamp;
- buffer->access->store_to(buffer, (u8 *)data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 28266d4..e5a33ff 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -455,12 +455,14 @@ out:
static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val)
{
- struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ struct iio_buffer *ring = indio_dev->buffer;
int ret;
s64 dat64[2];
u32 *dat32 = (u32 *)dat64;
- if (!(test_bit(ch, ring->scan_mask)))
+ if (!iio_is_primary_active(indio_dev) ||
+ !(test_bit(ch, ring->scan_mask)))
return -EBUSY;
ret = ring->access->read_last(ring, (u8 *) &dat64);
@@ -475,29 +477,30 @@ static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val)
static int ad7192_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7192_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
+ struct iio_buffer *buffer;
size_t d_size;
unsigned channel;
if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength);
-
- d_size = bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength) *
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ d_size = bitmap_weight(buffer->scan_mask,
+ indio_dev->masklength) *
indio_dev->channels[0].scan_type.storagebits / 8;
- if (ring->scan_timestamp) {
- d_size += sizeof(s64);
+ if (buffer->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (d_size % sizeof(s64))
+ d_size += sizeof(s64) - (d_size % sizeof(s64));
+ }
- if (d_size % sizeof(s64))
- d_size += sizeof(s64) - (d_size % sizeof(s64));
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, d_size);
}
- if (indio_dev->buffer->access->set_bytes_per_datum)
- indio_dev->buffer->access->
- set_bytes_per_datum(indio_dev->buffer, d_size);
+ channel = find_first_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength);
st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) |
AD7192_MODE_SEL(AD7192_MODE_CONT);
@@ -540,7 +543,6 @@ static irqreturn_t ad7192_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *ring = indio_dev->buffer;
struct ad7192_state *st = iio_priv(indio_dev);
s64 dat64[2];
s32 *dat32 = (s32 *)dat64;
@@ -551,10 +553,10 @@ static irqreturn_t ad7192_trigger_handler(int irq, void *p)
indio_dev->channels[0].scan_type.realbits/8);
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
dat64[1] = pf->timestamp;
- ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)dat64, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
st->irq_dis = false;
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 5695eb2..42ad999 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -24,7 +24,8 @@ int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch)
int ret;
u16 *ring_data;
- if (!(test_bit(ch, ring->scan_mask))) {
+ if (!iio_is_primary_active(indio_dev) ||
+ !(test_bit(ch, ring->scan_mask))) {
ret = -EBUSY;
goto error_ret;
}
@@ -35,7 +36,7 @@ int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch)
ret = -ENOMEM;
goto error_ret;
}
- ret = ring->access->read_last(ring, (u8 *) ring_data);
+ ret = ring->access->read_last(ring, (u8 *)ring_data);
if (ret)
goto error_free_ring_data;
@@ -57,24 +58,38 @@ error_ret:
static int ad7298_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7298_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
+ struct iio_buffer *buffer;
size_t d_size;
int i, m;
unsigned short command;
- int scan_count = bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength);
+ int scan_count;
+
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ scan_count = bitmap_weight(buffer->scan_mask,
+ indio_dev->masklength);
+ d_size = scan_count * (AD7298_STORAGE_BITS / 8);
+
+ if (buffer->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (d_size % sizeof(s64))
+ d_size += sizeof(s64) - (d_size % sizeof(s64));
+ }
+
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, d_size);
+ }
+
+ /* Now compute overall size */
+ scan_count = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
d_size = scan_count * (AD7298_STORAGE_BITS / 8);
- if (ring->scan_timestamp) {
+ if (indio_dev->scan_timestamp) {
d_size += sizeof(s64);
-
if (d_size % sizeof(s64))
d_size += sizeof(s64) - (d_size % sizeof(s64));
}
- if (ring->access->set_bytes_per_datum)
- ring->access->set_bytes_per_datum(ring, d_size);
-
st->d_size = d_size;
command = AD7298_WRITE | st->ext_ref;
@@ -120,7 +135,6 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7298_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
s64 time_ns;
__u16 buf[16];
int b_sent, i;
@@ -129,17 +143,17 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
if (b_sent)
return b_sent;
- if (ring->scan_timestamp) {
+ if (indio_dev->scan_timestamp) {
time_ns = iio_get_time_ns();
memcpy((u8 *)buf + st->d_size - sizeof(s64),
&time_ns, sizeof(time_ns));
}
for (i = 0; i < bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength); i++)
+ indio_dev->masklength); i++)
buf[i] = be16_to_cpu(st->rx_buf[i]);
- indio_dev->buffer->access->store_to(ring, (u8 *)buf, time_ns);
+ iio_push_to_buffers(indio_dev, (u8 *)buf, time_ns);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index ff0656a..7e01f3e 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -26,6 +26,9 @@ int ad7476_scan_from_ring(struct iio_dev *indio_dev)
int ret;
u8 *ring_data;
+ if (!iio_is_primary_active(indio_dev))
+ return -EBUSY;
+
ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
GFP_KERNEL);
if (ring_data == NULL) {
@@ -54,23 +57,32 @@ error_ret:
static int ad7476_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7476_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
-
+ struct iio_buffer *buffer;
+ int d_size;
st->d_size = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength) *
st->chip_info->channel[0].scan_type.storagebits / 8;
- if (ring->scan_timestamp) {
- st->d_size += sizeof(s64);
-
+ if (indio_dev->scan_timestamp) {
+ d_size += sizeof(s64);
if (st->d_size % sizeof(s64))
st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
}
- if (indio_dev->buffer->access->set_bytes_per_datum)
- indio_dev->buffer->access->
- set_bytes_per_datum(indio_dev->buffer, st->d_size);
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ d_size = bitmap_weight(buffer->scan_mask,
+ indio_dev->masklength) *
+ st->chip_info->channel[0].scan_type.storagebits / 8;
+ if (buffer->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (st->d_size % sizeof(s64))
+ d_size += sizeof(s64) -
+ (st->d_size % sizeof(s64));
+ }
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, st->d_size);
+ }
return 0;
}
@@ -94,11 +106,11 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
time_ns = iio_get_time_ns();
- if (indio_dev->buffer->scan_timestamp)
+ if (indio_dev->scan_timestamp)
memcpy(rxbuf + st->d_size - sizeof(s64),
&time_ns, sizeof(time_ns));
- indio_dev->buffer->access->store_to(indio_dev->buffer, rxbuf, time_ns);
+ iio_push_to_buffers(indio_dev, rxbuf, time_ns);
done:
iio_trigger_notify_done(indio_dev->trig);
kfree(rxbuf);
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index f682af6..7086c18 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -70,13 +70,18 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
struct ad7606_state *st = container_of(work_s, struct ad7606_state,
poll_work);
struct iio_dev *indio_dev = iio_priv_to_dev(st);
- struct iio_buffer *ring = indio_dev->buffer;
s64 time_ns;
__u8 *buf;
- int ret;
+ int ret, scan_size;
- buf = kzalloc(ring->access->get_bytes_per_datum(ring),
- GFP_KERNEL);
+ scan_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+ if (indio_dev->scan_timestamp) {
+ if (scan_size % sizeof(s64))
+ scan_size += sizeof(s64) - scan_size % sizeof(s64);
+ scan_size += sizeof(s64);
+ }
+ buf = kzalloc(scan_size, GFP_KERNEL);
if (buf == NULL)
return;
@@ -106,11 +111,10 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
time_ns = iio_get_time_ns();
- if (ring->scan_timestamp)
- *((s64 *)(buf + ring->access->get_bytes_per_datum(ring) -
- sizeof(s64))) = time_ns;
+ if (indio_dev->scan_timestamp)
+ *((s64 *)(buf + scan_size - sizeof(s64))) = time_ns;
- ring->access->store_to(indio_dev->buffer, buf, time_ns);
+ iio_push_to_buffers(indio_dev, buf, time_ns);
done:
gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index dfc904c..008d2d3 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -317,12 +317,14 @@ out:
static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val)
{
- struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ struct iio_buffer *ring = indio_dev->buffer;
int ret;
s64 dat64[2];
u32 *dat32 = (u32 *)dat64;
- if (!(test_bit(ch, ring->scan_mask)))
+ if (!iio_is_primary_active(indio_dev) ||
+ !(test_bit(ch, ring->scan_mask)))
return -EBUSY;
ret = ring->access->read_last(ring, (u8 *) &dat64);
@@ -337,30 +339,29 @@ static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val)
static int ad7793_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7793_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
+ struct iio_buffer *buffer;
size_t d_size;
unsigned channel;
if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- channel = find_first_bit(indio_dev->active_scan_mask,
- indio_dev->masklength);
-
- d_size = bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength) *
- indio_dev->channels[0].scan_type.storagebits / 8;
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ d_size = bitmap_weight(buffer->scan_mask,
+ indio_dev->masklength) *
+ indio_dev->channels[0].scan_type.storagebits / 8;
- if (ring->scan_timestamp) {
- d_size += sizeof(s64);
-
- if (d_size % sizeof(s64))
- d_size += sizeof(s64) - (d_size % sizeof(s64));
+ if (buffer->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (d_size % sizeof(s64))
+ d_size += sizeof(s64) - (d_size % sizeof(s64));
+ }
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, d_size);
}
- if (indio_dev->buffer->access->set_bytes_per_datum)
- indio_dev->buffer->access->
- set_bytes_per_datum(indio_dev->buffer, d_size);
+ channel = find_first_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength);
st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) |
AD7793_MODE_SEL(AD7793_MODE_CONT);
@@ -406,7 +407,6 @@ static irqreturn_t ad7793_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *ring = indio_dev->buffer;
struct ad7793_state *st = iio_priv(indio_dev);
s64 dat64[2];
s32 *dat32 = (s32 *)dat64;
@@ -417,10 +417,10 @@ static irqreturn_t ad7793_trigger_handler(int irq, void *p)
indio_dev->channels[0].scan_type.realbits/8);
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
dat64[1] = pf->timestamp;
- ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)dat64, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
st->irq_dis = false;
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index f53a663..ac89fb3 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -21,11 +21,13 @@
int ad7887_scan_from_ring(struct ad7887_state *st, int channum)
{
- struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ struct iio_buffer *ring = indio_dev->buffer;
int count = 0, ret;
u16 *ring_data;
- if (!(test_bit(channum, ring->scan_mask))) {
+ if (!iio_is_primary_active(indio_dev) ||
+ !(test_bit(channum, ring->scan_mask))) {
ret = -EBUSY;
goto error_ret;
}
@@ -63,23 +65,32 @@ error_ret:
static int ad7887_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
-
+ struct iio_buffer *buffer;
+ int d_size;
st->d_size = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength) *
st->chip_info->channel[0].scan_type.storagebits / 8;
- if (ring->scan_timestamp) {
+ if (indio_dev->scan_timestamp) {
st->d_size += sizeof(s64);
if (st->d_size % sizeof(s64))
st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
}
- if (indio_dev->buffer->access->set_bytes_per_datum)
- indio_dev->buffer->access->
- set_bytes_per_datum(indio_dev->buffer, st->d_size);
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) *
+ st->chip_info->channel[0].scan_type.storagebits / 8;
+ if (buffer->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (d_size % sizeof(s64))
+ d_size += sizeof(s64) - (d_size % sizeof(s64));
+ }
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, d_size);
+ }
/* We know this is a single long so can 'cheat' */
switch (*indio_dev->active_scan_mask) {
case (1 << 0):
@@ -117,7 +128,6 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7887_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
s64 time_ns;
__u8 *buf;
int b_sent;
@@ -137,11 +147,11 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
time_ns = iio_get_time_ns();
memcpy(buf, st->data, bytes);
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
memcpy(buf + st->d_size - sizeof(s64),
&time_ns, sizeof(time_ns));
- indio_dev->buffer->access->store_to(indio_dev->buffer, buf, time_ns);
+ iio_push_to_buffers(indio_dev, buf, time_ns);
done:
kfree(buf);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 12a43db..9269e60 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -29,7 +29,8 @@ int ad799x_single_channel_from_ring(struct iio_dev *indio_dev, int channum)
int count = 0, ret;
u16 *ring_data;
- if (!(test_bit(channum, ring->scan_mask))) {
+ if (!iio_is_primary_active(indio_dev) ||
+ !(test_bit(channum, ring->scan_mask))) {
ret = -EBUSY;
goto error_ret;
}
@@ -62,9 +63,9 @@ error_ret:
**/
static int ad799x_ring_preenable(struct iio_dev *indio_dev)
{
- struct iio_buffer *ring = indio_dev->buffer;
+ struct iio_buffer *buffer;
struct ad799x_state *st = iio_priv(indio_dev);
-
+ int d_size;
/*
* Need to figure out the current mode based upon the requested
* scan mask in iio_dev
@@ -76,17 +77,23 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev)
st->d_size = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength) * 2;
- if (ring->scan_timestamp) {
+ if (indio_dev->scan_timestamp) {
st->d_size += sizeof(s64);
-
if (st->d_size % sizeof(s64))
- st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
+ st->d_size += sizeof(s64) -
+ (st->d_size % sizeof(s64));
+ }
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ d_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength) * 2;
+ if (buffer->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (d_size % sizeof(s64))
+ d_size += sizeof(s64) - (d_size % sizeof(s64));
+ }
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, d_size);
}
-
- if (indio_dev->buffer->access->set_bytes_per_datum)
- indio_dev->buffer->access->
- set_bytes_per_datum(indio_dev->buffer, st->d_size);
-
return 0;
}
@@ -102,7 +109,6 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad799x_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
s64 time_ns;
__u8 *rxbuf;
int b_sent;
@@ -140,11 +146,11 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
time_ns = iio_get_time_ns();
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
memcpy(rxbuf + st->d_size - sizeof(s64),
&time_ns, sizeof(time_ns));
- ring->access->store_to(indio_dev->buffer, rxbuf, time_ns);
+ iio_push_to_buffers(indio_dev, rxbuf, time_ns);
done:
kfree(rxbuf);
if (b_sent < 0)
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index 3a38a26..b52ec5b 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -23,28 +23,32 @@
int max1363_single_channel_from_ring(const long *mask, struct max1363_state *st)
{
- struct iio_buffer *ring = iio_priv_to_dev(st)->buffer;
+ struct iio_dev *indio_dev = iio_priv_to_dev(st);
+ struct iio_buffer *buffer = indio_dev->buffer;
int count = 0, ret, index;
u8 *ring_data;
index = find_first_bit(mask, MAX1363_MAX_CHANNELS);
- if (!(test_bit(index, st->current_mode->modemask))) {
+ if (!iio_is_primary_active(indio_dev))
+ return -EBUSY;
+ if (!(test_bit(index, indio_dev->buffer->scan_mask))) {
ret = -EBUSY;
goto error_ret;
}
- ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+ ring_data = kmalloc(buffer->access->
+ get_bytes_per_datum(indio_dev->buffer),
GFP_KERNEL);
if (ring_data == NULL) {
ret = -ENOMEM;
goto error_ret;
}
- ret = ring->access->read_last(ring, ring_data);
+ ret = buffer->access->read_last(indio_dev->buffer, ring_data);
if (ret)
goto error_free_ring_data;
/* Need a count of channels prior to this one */
- count = bitmap_weight(mask, index - 1);
+ count = bitmap_weight(indio_dev->buffer->scan_mask, index - 1);
if (st->chip_info->bits != 8)
ret = ((int)(ring_data[count*2 + 0] & 0x0F) << 8)
+ (int)(ring_data[count*2 + 1]);
@@ -90,7 +94,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
d_size = numvals*2;
else
d_size = numvals;
- if (indio_dev->buffer->scan_timestamp) {
+ if (indio_dev->scan_timestamp) {
d_size += sizeof(s64);
if (d_size % sizeof(s64))
d_size += sizeof(s64) - (d_size % sizeof(s64));
@@ -114,9 +118,9 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
time_ns = iio_get_time_ns();
- if (indio_dev->buffer->scan_timestamp)
+ if (indio_dev->scan_timestamp)
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
- iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns);
+ iio_push_to_buffers(indio_dev, rxbuf, time_ns);
done:
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h
index 7fc0894..cdfc15b 100644
--- a/drivers/staging/iio/buffer.h
+++ b/drivers/staging/iio/buffer.h
@@ -99,8 +99,11 @@ struct iio_buffer {
const struct attribute_group *attrs;
struct list_head demux_list;
unsigned char *demux_bounce;
+ struct list_head buffer_list;
};
+bool iio_is_primary_active(struct iio_dev *indio_dev);
+
/**
* iio_buffer_init() - Initialize the buffer structure
* @buffer: buffer to be initialized
@@ -145,6 +148,9 @@ int iio_scan_mask_set(struct iio_buffer *buffer, int bit);
int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data,
s64 timestamp);
+int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data,
+ s64 timestamp);
+
int iio_update_demux(struct iio_dev *indio_dev);
/**
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 6a9b5db4..f87c1fc 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -62,12 +62,20 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16260_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
int i = 0;
s16 *data;
- size_t datasize = ring->access->get_bytes_per_datum(ring);
+ size_t data_size;
- data = kmalloc(datasize , GFP_KERNEL);
+ data_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength)*2;
+
+ if (indio_dev->scan_timestamp) {
+ if (data_size % sizeof(s64))
+ data_size += sizeof(s64) - data_size % sizeof(s64);
+ data_size += sizeof(s64);
+ }
+
+ data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
dev_err(&st->us->dev, "memory alloc failed in ring bh");
return -ENOMEM;
@@ -80,10 +88,10 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
kfree(data);
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index bd29412..19d1741 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -322,11 +322,13 @@ struct iio_dev {
struct iio_event_interface *event_interface;
struct iio_buffer *buffer;
+ struct list_head buffer_list;
struct mutex mlock;
unsigned long *available_scan_masks;
unsigned masklength;
unsigned long *active_scan_mask;
+ bool scan_timestamp;
struct iio_trigger *trig;
struct iio_poll_func *pollfunc;
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index c572f8b..d2c41d4 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -45,18 +45,26 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *buffer = indio_dev->buffer;
int len = 0;
/*
* The datasize is obtained from the buffer. It was stored when
* the preenable setup function was called.
*/
- size_t datasize = buffer->access->get_bytes_per_datum(buffer);
- u16 *data = kmalloc(datasize, GFP_KERNEL);
+ size_t data_size;
+ u16 *data;
+
+ data_size = bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength);
+ if (indio_dev->scan_timestamp) {
+ if (data_size % sizeof(s64))
+ data_size += sizeof(s64) - (data_size % sizeof(s64));
+ data_size += sizeof(s64);
+ }
+ data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
- if (buffer->scan_count) {
+ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
/*
* Three common options here:
* hardware scans: certain combinations of channels make
@@ -74,8 +82,9 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
* in the constant table fakedata.
*/
int i, j;
- for (i = 0, j = 0; i < buffer->scan_count; i++) {
- j = find_next_bit(buffer->scan_mask,
+ for (i = 0, j = 0; i < bitmap_weight(indio_dev->active_scan_mask,
+ indio_dev->masklength); i++) {
+ j = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength, j + 1);
/* random access read form the 'device' */
data[i] = fakedata[j];
@@ -83,11 +92,11 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
}
}
/* Store a timestampe at an 8 byte boundary */
- if (buffer->scan_timestamp)
+ if (indio_dev->scan_timestamp)
*(s64 *)(((phys_addr_t)data + len
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
= iio_get_time_ns();
- buffer->access->store_to(buffer, (u8 *)data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)data, pf->timestamp);
kfree(data);
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 8da86b7..c21a69a 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -539,17 +539,19 @@ static int ad5933_ring_preenable(struct iio_dev *indio_dev)
struct ad5933_state *st = iio_priv(indio_dev);
size_t d_size;
int ret;
+ struct iio_buffer *buffer;
if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- d_size = bitmap_weight(indio_dev->active_scan_mask,
- indio_dev->masklength) *
- ad5933_channels[1].scan_type.storagebits / 8;
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ d_size = bitmap_weight(buffer->scan_mask,
+ indio_dev->masklength) *
+ ad5933_channels[1].scan_type.storagebits / 8;
- if (indio_dev->buffer->access->set_bytes_per_datum)
- indio_dev->buffer->access->
- set_bytes_per_datum(indio_dev->buffer, d_size);
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, d_size);
+ }
ret = ad5933_reset(st);
if (ret < 0)
@@ -623,7 +625,6 @@ static void ad5933_work(struct work_struct *work)
struct ad5933_state *st = container_of(work,
struct ad5933_state, work.work);
struct iio_dev *indio_dev = i2c_get_clientdata(st->client);
- struct iio_buffer *ring = indio_dev->buffer;
signed short buf[2];
unsigned char status;
@@ -654,7 +655,7 @@ static void ad5933_work(struct work_struct *work)
buf[0] = be16_to_cpu(buf[0]);
}
/* save datum to the ring */
- ring->access->store_to(ring, (u8 *)buf, iio_get_time_ns());
+ iio_push_to_buffers(indio_dev, (u8 *)buf, iio_get_time_ns());
} else {
/* no data available - try again later */
schedule_delayed_work(&st->work, st->poll_time_jiffies);
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index 9506e05..44f3ee2 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -151,7 +151,7 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
/* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
- ring->access->store_to(indio_dev->buffer, (u8 *) data, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *) data, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c
index 5f9ed47..ac47eba 100644
--- a/drivers/staging/iio/industrialio-buffer.c
+++ b/drivers/staging/iio/industrialio-buffer.c
@@ -30,6 +30,17 @@ static const char * const iio_endian_prefix[] = {
[IIO_LE] = "le",
};
+bool iio_is_primary_active(struct iio_dev *indio_dev)
+{
+ struct list_head *p;
+
+ list_for_each(p, &indio_dev->buffer_list)
+ if (p == &indio_dev->buffer->buffer_list)
+ return true;
+ return false;
+}
+EXPORT_SYMBOL_GPL(iio_is_primary_active);
+
/**
* iio_buffer_read_first_n_outer() - chrdev read for buffer access
*
@@ -136,7 +147,6 @@ static ssize_t iio_scan_el_show(struct device *dev,
static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit)
{
clear_bit(bit, buffer->scan_mask);
- buffer->scan_count--;
return 0;
}
@@ -145,15 +155,17 @@ static ssize_t iio_scan_el_store(struct device *dev,
const char *buf,
size_t len)
{
- int ret = 0;
+ int ret;
bool state;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct iio_buffer *buffer = indio_dev->buffer;
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
- state = !(buf[0] == '0');
+ ret = strtobool(buf, &state);
+ if (ret < 0)
+ return ret;
mutex_lock(&indio_dev->mlock);
- if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
+ if (iio_is_primary_active(indio_dev)) {
ret = -EBUSY;
goto error_ret;
}
@@ -190,13 +202,16 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
const char *buf,
size_t len)
{
- int ret = 0;
+ int ret;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
bool state;
- state = !(buf[0] == '0');
+ ret = strtobool(buf, &state);
+ if (ret < 0)
+ return ret;
+
mutex_lock(&indio_dev->mlock);
- if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
+ if (iio_is_primary_active(indio_dev)) {
ret = -EBUSY;
goto error_ret;
}
@@ -298,34 +313,41 @@ int iio_buffer_register(struct iio_dev *indio_dev,
attrcount = attrcount_orig;
INIT_LIST_HEAD(&buffer->demux_list);
INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list);
- if (channels) {
- /* new magic */
- for (i = 0; i < num_channels; i++) {
- /* Establish necessary mask length */
- if (channels[i].scan_index >
- (int)indio_dev->masklength - 1)
- indio_dev->masklength
- = indio_dev->channels[i].scan_index + 1;
+ /* new magic */
+ for (i = 0; i < num_channels; i++) {
+ /* Establish necessary mask length */
+ if (channels[i].scan_index >
+ (int)indio_dev->masklength - 1)
+ indio_dev->masklength
+ = indio_dev->channels[i].scan_index + 1;
- ret = iio_buffer_add_channel_sysfs(indio_dev,
+ ret = iio_buffer_add_channel_sysfs(indio_dev,
&channels[i]);
- if (ret < 0)
- goto error_cleanup_dynamic;
- attrcount += ret;
- if (channels[i].type == IIO_TIMESTAMP)
- buffer->scan_index_timestamp = channels[i].scan_index;
- }
- if (indio_dev->masklength && buffer->scan_mask == NULL) {
- buffer->scan_mask
- = kzalloc(sizeof(*buffer->scan_mask)*
- BITS_TO_LONGS(indio_dev->masklength),
- GFP_KERNEL);
- if (buffer->scan_mask == NULL) {
- ret = -ENOMEM;
- goto error_cleanup_dynamic;
- }
+ if (ret < 0)
+ goto error_cleanup_dynamic;
+ attrcount += ret;
+ if (channels[i].type == IIO_TIMESTAMP)
+ buffer->scan_index_timestamp = channels[i].scan_index;
+ }
+ if (indio_dev->masklength && buffer->scan_mask == NULL) {
+ buffer->scan_mask
+ = kzalloc(sizeof(*buffer->scan_mask)*
+ BITS_TO_LONGS(indio_dev->masklength),
+ GFP_KERNEL);
+ if (buffer->scan_mask == NULL) {
+ ret = -ENOMEM;
+ goto error_cleanup_dynamic;
}
}
+ indio_dev->active_scan_mask =
+ kzalloc(sizeof(*buffer->scan_mask)*
+ BITS_TO_LONGS(indio_dev->masklength),
+ GFP_KERNEL);
+ BUG_ON(indio_dev->masklength == 0);
+ if (indio_dev->active_scan_mask == NULL) {
+ ret = -ENOMEM;
+ goto error_free_scan_mask;
+ }
buffer->scan_el_group.name = iio_scan_elements_group_name;
@@ -408,94 +430,187 @@ ssize_t iio_buffer_write_length(struct device *dev,
}
EXPORT_SYMBOL(iio_buffer_write_length);
+static unsigned long *iio_scan_mask_match(unsigned long *av_masks,
+ unsigned int masklength,
+ unsigned long *mask)
+{
+ if (bitmap_empty(mask, masklength))
+ return NULL;
+ while (*av_masks) {
+ if (bitmap_subset(mask, av_masks, masklength))
+ return av_masks;
+ av_masks += BITS_TO_LONGS(masklength);
+ }
+ return NULL;
+}
+
+static int iio_update_buffers(struct iio_dev *indio_dev,
+ struct iio_buffer *insert_buffer,
+ struct iio_buffer *remove_buffer)
+{
+ int ret;
+ struct iio_buffer *buffer;
+ unsigned long *compound_mask;
+/* Wind down existing buffers - iff there are any */
+
+ if (!list_empty(&indio_dev->buffer_list)) {
+ /* First predisable */
+ if (indio_dev->setup_ops->predisable) {
+ ret = indio_dev->setup_ops->predisable(indio_dev);
+ if (ret)
+ goto error_ret;
+ }
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
+ if (buffer->access->unmark_in_use)
+ buffer->access->unmark_in_use(buffer);
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+ if (indio_dev->setup_ops->postdisable) {
+ ret = indio_dev->setup_ops->postdisable(indio_dev);
+ if (ret)
+ goto error_ret;
+ }
+ }
+ if (insert_buffer)
+ list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
+ if (remove_buffer)
+ list_del(&remove_buffer->buffer_list);
+ /* If no buffers in list, we are done */
+ if (list_empty(&indio_dev->buffer_list))
+ return 0;
+
+ /* What scan mask do we actually have ?*/
+ compound_mask = kzalloc(BITS_TO_LONGS(indio_dev->masklength)
+ *sizeof(long), GFP_KERNEL);
+ if (compound_mask == NULL)
+ return -ENOMEM;
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ bitmap_or(compound_mask, compound_mask, buffer->scan_mask,
+ indio_dev->masklength);
+ indio_dev->scan_timestamp |= buffer->scan_timestamp;
+ }
+ if (indio_dev->available_scan_masks) {
+ bitmap_copy(indio_dev->active_scan_mask,
+ iio_scan_mask_match(indio_dev->available_scan_masks,
+ indio_dev->masklength,
+ compound_mask),
+ indio_dev->masklength);
+ } else
+ bitmap_copy(indio_dev->active_scan_mask,
+ compound_mask,
+ indio_dev->masklength);
+
+ iio_update_demux(indio_dev);
+/* Wind up again */
+ if (indio_dev->setup_ops->preenable) {
+ ret = indio_dev->setup_ops->preenable(indio_dev);
+ if (ret) {
+ printk(KERN_ERR
+ "Buffer not started:"
+ "buffer preenable failed\n");
+ goto error_free_compound_mask;
+ }
+ }
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ if (buffer->access->request_update) {
+ ret = buffer->access->request_update(buffer);
+ if (ret) {
+ printk(KERN_INFO
+ "Buffer not started:"
+ "buffer parameter update failed\n");
+ goto error_ret;
+ }
+ }
+ if (buffer->access->mark_in_use)
+ buffer->access->mark_in_use(buffer);
+ }
+ if (indio_dev->info->update_scan_mode) {
+ ret = indio_dev->info
+ ->update_scan_mode(indio_dev,
+ indio_dev->active_scan_mask);
+ if (ret < 0)
+ goto error_free_compound_mask;
+ }
+ /* Definitely possible for devices to support both of these.*/
+ if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
+ if (!indio_dev->trig) {
+ printk(KERN_INFO
+ "Buffer not started: no trigger\n");
+ ret = -EINVAL;
+ if (buffer->access->unmark_in_use)
+ buffer->access->unmark_in_use(buffer);
+ goto error_free_compound_mask;
+ }
+ indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
+ } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE)
+ indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
+ else { /* should never be reached */
+ ret = -EINVAL;
+ goto error_free_compound_mask;
+ }
+
+ if (indio_dev->setup_ops->postenable) {
+ ret = indio_dev->setup_ops->postenable(indio_dev);
+ if (ret) {
+ printk(KERN_INFO
+ "Buffer not started:"
+ "postenable failed\n");
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ if (buffer->access->unmark_in_use)
+ buffer->access->unmark_in_use(buffer);
+ indio_dev->currentmode = INDIO_DIRECT_MODE;
+ if (indio_dev->setup_ops->postdisable)
+ indio_dev->setup_ops->
+ postdisable(indio_dev);
+ goto error_free_compound_mask;
+ }
+ }
+ }
+error_free_compound_mask:
+ kfree(compound_mask);
+error_ret:
+ return ret;
+}
+
ssize_t iio_buffer_store_enable(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
int ret;
- bool requested_state, current_state;
- int previous_mode;
+ bool requested_state;
struct iio_dev *indio_dev = dev_get_drvdata(dev);
- struct iio_buffer *buffer = indio_dev->buffer;
+ struct iio_buffer *pbuf = indio_dev->buffer;
+ struct list_head *p;
+ bool inlist = false;
+
+ ret = strtobool(buf, &requested_state);
+ if (ret < 0)
+ return ret;
mutex_lock(&indio_dev->mlock);
- previous_mode = indio_dev->currentmode;
- requested_state = !(buf[0] == '0');
- current_state = !!(previous_mode & INDIO_ALL_BUFFER_MODES);
- if (current_state == requested_state) {
- printk(KERN_INFO "iio-buffer, current state requested again\n");
- goto done;
- }
- if (requested_state) {
- if (indio_dev->setup_ops->preenable) {
- ret = indio_dev->setup_ops->preenable(indio_dev);
- if (ret) {
- printk(KERN_ERR
- "Buffer not started:"
- "buffer preenable failed\n");
- goto error_ret;
- }
- }
- if (buffer->access->request_update) {
- ret = buffer->access->request_update(buffer);
- if (ret) {
- printk(KERN_INFO
- "Buffer not started:"
- "buffer parameter update failed\n");
- goto error_ret;
- }
- }
- if (buffer->access->mark_in_use)
- buffer->access->mark_in_use(buffer);
- /* Definitely possible for devices to support both of these.*/
- if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
- if (!indio_dev->trig) {
- printk(KERN_INFO
- "Buffer not started: no trigger\n");
- ret = -EINVAL;
- if (buffer->access->unmark_in_use)
- buffer->access->unmark_in_use(buffer);
- goto error_ret;
- }
- indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
- } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE)
- indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
- else { /* should never be reached */
- ret = -EINVAL;
- goto error_ret;
- }
- if (indio_dev->setup_ops->postenable) {
- ret = indio_dev->setup_ops->postenable(indio_dev);
- if (ret) {
- printk(KERN_INFO
- "Buffer not started:"
- "postenable failed\n");
- if (buffer->access->unmark_in_use)
- buffer->access->unmark_in_use(buffer);
- indio_dev->currentmode = previous_mode;
- if (indio_dev->setup_ops->postdisable)
- indio_dev->setup_ops->
- postdisable(indio_dev);
- goto error_ret;
- }
+ /* Find out if it is in the list */
+ list_for_each(p, &indio_dev->buffer_list)
+ if (p == &pbuf->buffer_list) {
+ inlist = true;
+ break;
}
- } else {
- if (indio_dev->setup_ops->predisable) {
- ret = indio_dev->setup_ops->predisable(indio_dev);
- if (ret)
- goto error_ret;
- }
- if (buffer->access->unmark_in_use)
- buffer->access->unmark_in_use(buffer);
- indio_dev->currentmode = INDIO_DIRECT_MODE;
- if (indio_dev->setup_ops->postdisable) {
- ret = indio_dev->setup_ops->postdisable(indio_dev);
- if (ret)
- goto error_ret;
- }
- }
+ /* Already enabled */
+ if (inlist && requested_state)
+ goto done;
+ /* Already disabled */
+ if (!inlist && !requested_state)
+ goto done;
+
+ if (requested_state)
+ ret = iio_update_buffers(indio_dev,
+ indio_dev->buffer, NULL);
+ else
+ ret = iio_update_buffers(indio_dev,
+ NULL, indio_dev->buffer);
+
+ if (ret < 0)
+ goto error_ret;
done:
mutex_unlock(&indio_dev->mlock);
return len;
@@ -516,62 +631,35 @@ ssize_t iio_buffer_show_enable(struct device *dev,
}
EXPORT_SYMBOL(iio_buffer_show_enable);
-/* note NULL used as error indicator as it doesn't make sense. */
-static unsigned long *iio_scan_mask_match(unsigned long *av_masks,
- unsigned int masklength,
- unsigned long *mask)
-{
- if (bitmap_empty(mask, masklength))
- return NULL;
- while (*av_masks) {
- if (bitmap_subset(mask, av_masks, masklength))
- return av_masks;
- av_masks += BITS_TO_LONGS(masklength);
- }
- return NULL;
-}
-
int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
{
- struct iio_buffer *buffer = indio_dev->buffer;
+ struct iio_buffer *buffer;
const struct iio_chan_spec *ch;
unsigned bytes = 0;
int length, i;
dev_dbg(&indio_dev->dev, "%s\n", __func__);
- /* How much space will the demuxed element take? */
- for_each_set_bit(i, buffer->scan_mask,
- indio_dev->masklength) {
- ch = iio_find_channel_from_si(indio_dev, i);
- length = ch->scan_type.storagebits/8;
- if (bytes % length)
- bytes += length - bytes % length;
- bytes += length;
- }
- if (buffer->scan_timestamp) {
- ch = iio_find_channel_from_si(indio_dev,
- buffer->scan_index_timestamp);
- length = ch->scan_type.storagebits/8;
- if (bytes % length)
- bytes += length - bytes % length;
- bytes += length;
- }
- buffer->access->set_bytes_per_datum(buffer, bytes);
-
- /* What scan mask do we actually have ?*/
- if (indio_dev->available_scan_masks)
- indio_dev->active_scan_mask =
- iio_scan_mask_match(indio_dev->available_scan_masks,
- indio_dev->masklength,
- buffer->scan_mask);
- else
- indio_dev->active_scan_mask = buffer->scan_mask;
- iio_update_demux(indio_dev);
-
- if (indio_dev->info->update_scan_mode)
- return indio_dev->info
- ->update_scan_mode(indio_dev,
- indio_dev->active_scan_mask);
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ /* How much space will the demuxed element take? */
+ for_each_set_bit(i, buffer->scan_mask,
+ indio_dev->masklength) {
+ ch = iio_find_channel_from_si(indio_dev, i);
+ length = ch->scan_type.storagebits / 8;
+ if (bytes % length)
+ bytes += length - bytes % length;
+ bytes += length;
+ }
+ if (buffer->scan_timestamp) {
+ ch = iio_find_channel_from_si(indio_dev,
+ buffer->scan_index_timestamp);
+ length = ch->scan_type.storagebits / 8;
+ if (bytes % length)
+ bytes += length - bytes % length;
+ bytes += length;
+ }
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, bytes);
+ }
return 0;
}
EXPORT_SYMBOL(iio_sw_buffer_preenable);
@@ -598,6 +686,7 @@ int iio_scan_mask_set(struct iio_buffer *buffer, int bit)
kfree(trialmask);
return -EINVAL;
}
+ ///* Possible this needs updating */
bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
set_bit(bit, trialmask);
@@ -610,8 +699,7 @@ int iio_scan_mask_set(struct iio_buffer *buffer, int bit)
return -EINVAL;
}
}
- bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength);
- buffer->scan_count++;
+ set_bit(bit, buffer->scan_mask);
kfree(trialmask);
@@ -679,98 +767,118 @@ int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data,
}
EXPORT_SYMBOL_GPL(iio_push_to_buffer);
+
+int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data,
+ s64 timestamp)
+{
+ int ret;
+ struct iio_buffer *buf;
+ list_for_each_entry(buf, &indio_dev->buffer_list, buffer_list) {
+ ret = iio_push_to_buffer(buf, data, timestamp);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iio_push_to_buffers);
+
int iio_update_demux(struct iio_dev *indio_dev)
{
const struct iio_chan_spec *ch;
- struct iio_buffer *buffer = indio_dev->buffer;
- int ret, in_ind = -1, out_ind, length;
- unsigned in_loc = 0, out_loc = 0;
+ struct iio_buffer *buffer;
struct iio_demux_table *p, *q;
+ int ret;
- /* Clear out any old demux */
- list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
- list_del(&p->l);
- kfree(p);
- }
- kfree(buffer->demux_bounce);
- buffer->demux_bounce = NULL;
-
- /* First work out which scan mode we will actually have */
- if (bitmap_equal(indio_dev->active_scan_mask,
- buffer->scan_mask,
- indio_dev->masklength))
- return 0;
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ unsigned in_loc = 0, out_loc = 0;
+ int in_ind = -1, out_ind, length;
+
+ /* Clear out any old demux */
+ list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
+ list_del(&p->l);
+ kfree(p);
+ }
+ kfree(buffer->demux_bounce);
+ buffer->demux_bounce = NULL;
- out_ind = find_first_bit(buffer->scan_mask, indio_dev->masklength);
- /* Now we have the two masks, work from least sig and build up sizes */
- while (out_ind != indio_dev->masklength) {
- in_ind = find_next_bit(indio_dev->active_scan_mask,
- indio_dev->masklength,
- in_ind + 1);
- while (in_ind != out_ind) {
+ /* First work out which scan mode we will actually have */
+ if (bitmap_equal(indio_dev->active_scan_mask,
+ buffer->scan_mask,
+ indio_dev->masklength))
+ return 0;
+ out_ind = find_first_bit(buffer->scan_mask, indio_dev->masklength);
+ /* Now we have the two masks, work from least sig and build up sizes */
+ while (out_ind != indio_dev->masklength) {
in_ind = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength,
in_ind + 1);
+ while (in_ind != out_ind) {
+ in_ind = find_next_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength,
+ in_ind + 1);
+ ch = iio_find_channel_from_si(indio_dev, in_ind);
+ length = ch->scan_type.storagebits/8;
+ /* Make sure we are aligned */
+ in_loc += length;
+ if (in_loc % length)
+ in_loc += length - in_loc % length;
+ }
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ ret = -ENOMEM;
+ goto error_clear_mux_table;
+ }
ch = iio_find_channel_from_si(indio_dev, in_ind);
length = ch->scan_type.storagebits/8;
- /* Make sure we are aligned */
- in_loc += length;
+ if (out_loc % length)
+ out_loc += length - out_loc % length;
if (in_loc % length)
in_loc += length - in_loc % length;
+ p->from = in_loc;
+ p->to = out_loc;
+ p->length = length;
+ list_add_tail(&p->l, &buffer->demux_list);
+ out_loc += length;
+ in_loc += length;
+ out_ind = find_next_bit(buffer->scan_mask,
+ indio_dev->masklength,
+ out_ind + 1);
}
- p = kmalloc(sizeof(*p), GFP_KERNEL);
- if (p == NULL) {
- ret = -ENOMEM;
- goto error_clear_mux_table;
+ /* Relies on scan_timestamp being last */
+ if (buffer->scan_timestamp) {
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ ret = -ENOMEM;
+ goto error_clear_mux_table;
+ }
+ ch = iio_find_channel_from_si(indio_dev,
+ buffer->scan_index_timestamp);
+ length = ch->scan_type.storagebits/8;
+ if (out_loc % length)
+ out_loc += length - out_loc % length;
+ if (in_loc % length)
+ in_loc += length - in_loc % length;
+ p->from = in_loc;
+ p->to = out_loc;
+ p->length = length;
+ list_add_tail(&p->l, &buffer->demux_list);
+ out_loc += length;
+ in_loc += length;
}
- ch = iio_find_channel_from_si(indio_dev, in_ind);
- length = ch->scan_type.storagebits/8;
- if (out_loc % length)
- out_loc += length - out_loc % length;
- if (in_loc % length)
- in_loc += length - in_loc % length;
- p->from = in_loc;
- p->to = out_loc;
- p->length = length;
- list_add_tail(&p->l, &buffer->demux_list);
- out_loc += length;
- in_loc += length;
- out_ind = find_next_bit(buffer->scan_mask,
- indio_dev->masklength,
- out_ind + 1);
- }
- /* Relies on scan_timestamp being last */
- if (buffer->scan_timestamp) {
- p = kmalloc(sizeof(*p), GFP_KERNEL);
- if (p == NULL) {
+ buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL);
+ if (buffer->demux_bounce == NULL) {
ret = -ENOMEM;
goto error_clear_mux_table;
}
- ch = iio_find_channel_from_si(indio_dev,
- buffer->scan_index_timestamp);
- length = ch->scan_type.storagebits/8;
- if (out_loc % length)
- out_loc += length - out_loc % length;
- if (in_loc % length)
- in_loc += length - in_loc % length;
- p->from = in_loc;
- p->to = out_loc;
- p->length = length;
- list_add_tail(&p->l, &buffer->demux_list);
- out_loc += length;
- in_loc += length;
- }
- buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL);
- if (buffer->demux_bounce == NULL) {
- ret = -ENOMEM;
- goto error_clear_mux_table;
}
return 0;
-
+
error_clear_mux_table:
- list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
- list_del(&p->l);
- kfree(p);
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
+ list_del(&p->l);
+ kfree(p);
+ }
}
return ret;
}
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 69c4c98b..29b7902 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -1313,6 +1313,7 @@ struct iio_dev *iio_allocate_device(int sizeof_priv)
return NULL;
}
dev_set_name(&dev->dev, "iio:device%d", dev->id);
+ INIT_LIST_HEAD(&dev->buffer_list);
}
return dev;
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 893d4b4..1d7a6f6 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -61,7 +61,6 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
- struct iio_buffer *ring = indio_dev->buffer;
struct ade7758_state *st = iio_priv(indio_dev);
s64 dat64[2];
u32 *dat32 = (u32 *)dat64;
@@ -71,10 +70,10 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
/* Guaranteed to be aligned with 8 byte boundary */
- if (ring->scan_timestamp)
+ if (indio_dev->scan_timestamp)
dat64[1] = pf->timestamp;
- ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
+ iio_push_to_buffers(indio_dev, (u8 *)dat64, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);
@@ -91,27 +90,26 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
static int ade7758_ring_preenable(struct iio_dev *indio_dev)
{
struct ade7758_state *st = iio_priv(indio_dev);
- struct iio_buffer *ring = indio_dev->buffer;
+ struct iio_buffer *buffer;
size_t d_size;
unsigned channel;
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
return -EINVAL;
- channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength);
+ list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+ d_size = st->ade7758_ring_channels[0].scan_type.storagebits / 8;
+ if (buffer->scan_timestamp) {
+ d_size += sizeof(s64);
+ if (d_size % sizeof(s64))
+ d_size += sizeof(s64) - (d_size % sizeof(s64));
+ }
- d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8;
-
- if (ring->scan_timestamp) {
- d_size += sizeof(s64);
-
- if (d_size % sizeof(s64))
- d_size += sizeof(s64) - (d_size % sizeof(s64));
+ if (buffer->access->set_bytes_per_datum)
+ buffer->access->set_bytes_per_datum(buffer, d_size);
}
-
- if (indio_dev->buffer->access->set_bytes_per_datum)
- indio_dev->buffer->access->
- set_bytes_per_datum(indio_dev->buffer, d_size);
+ channel = find_first_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength);
ade7758_write_waveform_type(&indio_dev->dev,
st->ade7758_ring_channels[channel].address);
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/7] staging:iio: make update buffers available outside iio.
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
` (4 preceding siblings ...)
2011-10-26 15:54 ` [PATCH 5/7] staging:iio: make all buffer access pass through the buffer_list Jonathan Cameron
@ 2011-10-26 15:54 ` Jonathan Cameron
2011-10-26 15:54 ` [PATCH 7/7] staging:iio:snoop example of rawest level of push interface Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
This may well go away depending on exactly what the interfaces
we end up on for this are.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
drivers/staging/iio/buffer.h | 4 ++++
drivers/staging/iio/industrialio-buffer.c | 7 ++++---
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h
index cdfc15b..eca2538 100644
--- a/drivers/staging/iio/buffer.h
+++ b/drivers/staging/iio/buffer.h
@@ -104,6 +104,10 @@ struct iio_buffer {
bool iio_is_primary_active(struct iio_dev *indio_dev);
+int iio_update_buffers(struct iio_dev *indio_dev,
+ struct iio_buffer *insert_buffer,
+ struct iio_buffer *remove_buffer);
+
/**
* iio_buffer_init() - Initialize the buffer structure
* @buffer: buffer to be initialized
diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c
index ac47eba..7f52f88 100644
--- a/drivers/staging/iio/industrialio-buffer.c
+++ b/drivers/staging/iio/industrialio-buffer.c
@@ -444,9 +444,9 @@ static unsigned long *iio_scan_mask_match(unsigned long *av_masks,
return NULL;
}
-static int iio_update_buffers(struct iio_dev *indio_dev,
- struct iio_buffer *insert_buffer,
- struct iio_buffer *remove_buffer)
+int iio_update_buffers(struct iio_dev *indio_dev,
+ struct iio_buffer *insert_buffer,
+ struct iio_buffer *remove_buffer)
{
int ret;
struct iio_buffer *buffer;
@@ -570,6 +570,7 @@ error_free_compound_mask:
error_ret:
return ret;
}
+EXPORT_SYMBOL_GPL(iio_update_buffers);
ssize_t iio_buffer_store_enable(struct device *dev,
struct device_attribute *attr,
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 7/7] staging:iio:snoop example of rawest level of push interface
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
` (5 preceding siblings ...)
2011-10-26 15:54 ` [PATCH 6/7] staging:iio: make update buffers available outside iio Jonathan Cameron
@ 2011-10-26 15:54 ` Jonathan Cameron
6 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2011-10-26 15:54 UTC (permalink / raw)
To: linux-iio
Cc: linus.ml.walleij, broonie, arnd, gregkh, thomas.petazzoni,
Michael.Hennerich, lars, Jonathan Cameron
This is called garbage in it's Kconfig entry for a reason,
but it shows how things work at the lowest possible level.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
drivers/staging/iio/Kconfig | 5 ++
drivers/staging/iio/Makefile | 1 +
drivers/staging/iio/iio_snoop.c | 94 +++++++++++++++++++++++++++++++++++++++
3 files changed, 100 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index ca139fb..f1dbc2c 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -12,6 +12,11 @@ menuconfig IIO
drivers/staging/iio/Documentation for more information.
if IIO
+config IIO_SNOOP
+ tristate "dubious hack driver"
+ help
+ Garbage.
+
config IIO_ST_HWMON
tristate "Hwmon driver that uses channels specified via iio maps"
depends on HWMON
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
index d5ca5cf..bd639ed 100644
--- a/drivers/staging/iio/Makefile
+++ b/drivers/staging/iio/Makefile
@@ -18,6 +18,7 @@ iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o
obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o
obj-$(CONFIG_IIO_ST_HWMON) += iio_hwmon.o
+obj-$(CONFIG_IIO_SNOOP) += iio_snoop.o
obj-y += accel/
obj-y += adc/
diff --git a/drivers/staging/iio/iio_snoop.c b/drivers/staging/iio/iio_snoop.c
new file mode 100644
index 0000000..1f5abdb
--- /dev/null
+++ b/drivers/staging/iio/iio_snoop.c
@@ -0,0 +1,94 @@
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include "buffer.h"
+#include "inkern.h"
+
+static int iio_snoop_store_to(struct iio_buffer *buffer, u8 *data, s64 timestamp)
+{
+ printk(" snoop %d %d\n", data[0], data[1]);
+ return 0;
+}
+
+static struct iio_buffer_access_funcs iio_snoop_access = {
+ .store_to = &iio_snoop_store_to,
+};
+
+struct iio_snoop_buffer {
+ struct iio_buffer buf;
+};
+
+struct iio_snoop_state {
+ struct iio_channel **channels;
+ struct iio_snoop_buffer buf;
+};
+
+static int __devinit iio_snoop_probe(struct platform_device *pdev)
+{
+ struct iio_snoop_state *st;
+ int ret;
+
+ printk("probing snoop\n");
+ st= kzalloc(sizeof(*st), GFP_KERNEL);
+ if (st == NULL)
+ return -ENOMEM;
+
+ st->channels = iio_st_channel_get_all(&pdev->dev, NULL);
+ if (IS_ERR(st->channels)) {
+ ret = PTR_ERR(st->channels);
+ goto error_free_state;
+ }
+
+ st->buf.buf.access = &iio_snoop_access;
+ //cheat.
+ st->buf.buf.scan_mask = kzalloc(sizeof(long)*10, GFP_KERNEL);
+ INIT_LIST_HEAD(&st->buf.buf.demux_list);
+ /* naughty ;) */
+ set_bit(3, st->buf.buf.scan_mask);
+
+ platform_set_drvdata(pdev, st);
+ printk("update bufffers\bn");
+ iio_update_buffers(st->channels[0]->indio_dev, &st->buf.buf, NULL);
+
+ return 0;
+error_free_state:
+ kfree(st);
+ return ret;
+}
+
+static int __devexit iio_snoop_remove(struct platform_device *pdev)
+{
+ struct iio_snoop_state *st = platform_get_drvdata(pdev);
+ iio_update_buffers(st->channels[0]->indio_dev, NULL, &st->buf.buf);
+ iio_st_channel_release_all(st->channels);
+
+ kfree(st);
+ return 0;
+}
+
+static struct platform_driver __refdata iio_snoop_driver = {
+ .driver = {
+ .name = "iio_snoop",
+ .owner = THIS_MODULE,
+ },
+ .probe = iio_snoop_probe,
+ .remove = __devexit_p(iio_snoop_remove),
+};
+
+static int iio_snoop_init(void)
+{
+ return platform_driver_register(&iio_snoop_driver);
+}
+module_init(iio_snoop_init);
+
+static void iio_snoop_exit(void)
+{
+ platform_driver_unregister(&iio_snoop_driver);
+}
+module_exit(iio_snoop_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("IIO snoop buffer driver");
+MODULE_LICENSE("GPL v2");
--
1.7.7
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2011-10-26 15:54 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-26 15:54 [RFC PATCH 0/7] staging:iio:towards an in kernel push interface Jonathan Cameron
2011-10-26 15:54 ` [PATCH 1/7] staging:iio:buffer drop bpe field Jonathan Cameron
2011-10-26 15:54 ` [PATCH 2/7] staging:iio; remove userspace access to bytes per datum Jonathan Cameron
2011-10-26 15:54 ` [PATCH 3/7] staging:iio:buffer move setup ops from buffer instance to iio_dev Jonathan Cameron
2011-10-26 15:54 ` [PATCH 4/7] staging:iio: scrap scan_count and ensure all drivers use active_scan_mask Jonathan Cameron
2011-10-26 15:54 ` [PATCH 5/7] staging:iio: make all buffer access pass through the buffer_list Jonathan Cameron
2011-10-26 15:54 ` [PATCH 6/7] staging:iio: make update buffers available outside iio Jonathan Cameron
2011-10-26 15:54 ` [PATCH 7/7] staging:iio:snoop example of rawest level of push interface Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).