* [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