From 1ba4c976ce9cb8f225d2c6e9e5838ed1c7ca546b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 8 Dec 2011 18:20:37 +0100 Subject: [PATCH] --- yaml --- r: 281271 b: refs/heads/master c: c6795ad4c7934a1db196697308ea0c3ac8b15f52 h: refs/heads/master i: 281269: ce3678bba1e32968ca9da0ee171c05a2dad0a4a9 281267: ea1fe57f358710a0b12f9a73ec6a03ed4dc0c94c 281263: 0e961541179acc6b537b8a98cebd97771bd4a4cc v: v3 --- [refs] | 2 +- .../drivers/staging/iio/accel/sca3000_core.c | 6 ++-- .../drivers/staging/iio/accel/sca3000_ring.c | 11 +++--- trunk/drivers/staging/iio/buffer.h | 23 ++++++------ .../drivers/staging/iio/gyro/adis16260_core.c | 15 +++----- .../staging/iio/impedance-analyzer/ad5933.c | 4 +-- .../drivers/staging/iio/industrialio-buffer.c | 15 ++++---- trunk/drivers/staging/iio/kfifo_buf.c | 2 +- trunk/drivers/staging/iio/ring_sw.c | 35 ++++++++++++++++++- trunk/drivers/staging/iio/types.h | 2 +- 10 files changed, 74 insertions(+), 41 deletions(-) diff --git a/[refs] b/[refs] index 03624b6c4687..894d0ce3501d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5f070a36d62e27f55dcdcee735da683fe85bc10f +refs/heads/master: c6795ad4c7934a1db196697308ea0c3ac8b15f52 diff --git a/trunk/drivers/staging/iio/accel/sca3000_core.c b/trunk/drivers/staging/iio/accel/sca3000_core.c index 1f30108fdb55..a1277d2700ee 100644 --- a/trunk/drivers/staging/iio/accel/sca3000_core.c +++ b/trunk/drivers/staging/iio/accel/sca3000_core.c @@ -1166,9 +1166,9 @@ static int __devinit sca3000_probe(struct spi_device *spi) if (ret < 0) goto error_unregister_dev; if (indio_dev->buffer) { - iio_scan_mask_set(indio_dev, indio_dev->buffer, 0); - iio_scan_mask_set(indio_dev, indio_dev->buffer, 1); - iio_scan_mask_set(indio_dev, indio_dev->buffer, 2); + iio_scan_mask_set(indio_dev->buffer, 0); + iio_scan_mask_set(indio_dev->buffer, 1); + iio_scan_mask_set(indio_dev->buffer, 2); } if (spi->irq) { diff --git a/trunk/drivers/staging/iio/accel/sca3000_ring.c b/trunk/drivers/staging/iio/accel/sca3000_ring.c index 6b824a11f7f4..6a27a95bbba5 100644 --- a/trunk/drivers/staging/iio/accel/sca3000_ring.c +++ b/trunk/drivers/staging/iio/accel/sca3000_ring.c @@ -157,7 +157,8 @@ static ssize_t sca3000_query_ring_int(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret, val; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; struct sca3000_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); @@ -178,7 +179,8 @@ static ssize_t sca3000_set_ring_int(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; struct sca3000_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long val; @@ -219,7 +221,8 @@ static ssize_t sca3000_show_buffer_scale(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; struct sca3000_state *st = iio_priv(indio_dev); return sprintf(buf, "0.%06d\n", 4*st->info->scale); @@ -264,7 +267,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev) buf = &ring->buf; buf->stufftoread = 0; buf->attrs = &sca3000_ring_attr; - iio_buffer_init(buf); + iio_buffer_init(buf, indio_dev); return buf; } diff --git a/trunk/drivers/staging/iio/buffer.h b/trunk/drivers/staging/iio/buffer.h index c69709925ba2..98e9efa0cdba 100644 --- a/trunk/drivers/staging/iio/buffer.h +++ b/trunk/drivers/staging/iio/buffer.h @@ -21,6 +21,7 @@ struct iio_buffer; * @mark_in_use: reference counting, typically to prevent module removal * @unmark_in_use: reduce reference count when no longer using buffer * @store_to: actually store stuff to the buffer + * @read_last: get the last element stored * @read_first_n: try to get a specified number of elements (must exist) * @mark_param_change: notify buffer that some relevant parameter has changed * Often this means the underlying storage may need to @@ -47,6 +48,7 @@ struct iio_buffer_access_funcs { void (*unmark_in_use)(struct iio_buffer *buffer); int (*store_to)(struct iio_buffer *buffer, u8 *data, s64 timestamp); + int (*read_last)(struct iio_buffer *buffer, u8 *data); int (*read_first_n)(struct iio_buffer *buffer, size_t n, char __user *buf); @@ -65,25 +67,21 @@ struct iio_buffer_access_funcs { /** * struct iio_buffer - general buffer structure + * @indio_dev: industrial I/O device structure * @length: [DEVICE] number of datums in buffer * @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_mask: [INTERN] bitmask used in masking scan mode elements - * @scan_index_timestamp:[INTERN] cache of the index to the timestamp * @scan_timestamp: [INTERN] does the scan mode include a timestamp * @access: [DRIVER] buffer access functions associated with the * implementation. - * @scan_el_dev_attr_list:[INTERN] list of scan element related attributes. - * @scan_el_group: [DRIVER] attribute group for those attributes not - * created from the iio_chan_info array. - * @pollq: [INTERN] wait queue to allow for polling on the buffer. - * @stufftoread: [INTERN] flag to indicate new data. * @flags: [INTERN] file ops related flags including busy flag. * @demux_list: [INTERN] list of operations required to demux the scan. * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. **/ struct iio_buffer { + struct iio_dev *indio_dev; int length; int bytes_per_datum; struct attribute_group *scan_el_attrs; @@ -104,8 +102,10 @@ struct iio_buffer { /** * iio_buffer_init() - Initialize the buffer structure * @buffer: buffer to be initialized + * @indio_dev: the iio device the buffer is assocated with **/ -void iio_buffer_init(struct iio_buffer *buffer); +void iio_buffer_init(struct iio_buffer *buffer, + struct iio_dev *indio_dev); void iio_buffer_deinit(struct iio_buffer *buffer); @@ -122,16 +122,17 @@ static inline void __iio_update_buffer(struct iio_buffer *buffer, buffer->length = length; } -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit); +int iio_scan_mask_query(struct iio_buffer *buffer, int bit); /** * iio_scan_mask_set() - set particular bit in the scan mask * @buffer: the buffer whose scan mask we are interested in * @bit: the bit to be set. **/ -int iio_scan_mask_set(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit); +int iio_scan_mask_set(struct iio_buffer *buffer, int bit); + +#define to_iio_buffer(d) \ + container_of(d, struct iio_buffer, dev) /** * iio_push_to_buffer() - push to a registered buffer. diff --git a/trunk/drivers/staging/iio/gyro/adis16260_core.c b/trunk/drivers/staging/iio/gyro/adis16260_core.c index 871f76bb3c38..5614a220f4a2 100644 --- a/trunk/drivers/staging/iio/gyro/adis16260_core.c +++ b/trunk/drivers/staging/iio/gyro/adis16260_core.c @@ -632,16 +632,11 @@ static int __devinit adis16260_probe(struct spi_device *spi) } if (indio_dev->buffer) { /* Set default scan mode */ - iio_scan_mask_set(indio_dev, indio_dev->buffer, - ADIS16260_SCAN_SUPPLY); - iio_scan_mask_set(indio_dev, indio_dev->buffer, - ADIS16260_SCAN_GYRO); - iio_scan_mask_set(indio_dev, indio_dev->buffer, - ADIS16260_SCAN_AUX_ADC); - iio_scan_mask_set(indio_dev, indio_dev->buffer, - ADIS16260_SCAN_TEMP); - iio_scan_mask_set(indio_dev, indio_dev->buffer, - ADIS16260_SCAN_ANGL); + iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_SUPPLY); + iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_GYRO); + iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_AUX_ADC); + iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_TEMP); + iio_scan_mask_set(indio_dev->buffer, ADIS16260_SCAN_ANGL); } if (spi->irq) { ret = adis16260_probe_trigger(indio_dev); diff --git a/trunk/drivers/staging/iio/impedance-analyzer/ad5933.c b/trunk/drivers/staging/iio/impedance-analyzer/ad5933.c index f02d1c06b454..23241c4ca03e 100644 --- a/trunk/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/trunk/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -736,8 +736,8 @@ static int __devinit ad5933_probe(struct i2c_client *client, goto error_unreg_ring; /* enable both REAL and IMAG channels by default */ - iio_scan_mask_set(indio_dev, indio_dev->buffer, 0); - iio_scan_mask_set(indio_dev, indio_dev->buffer, 1); + iio_scan_mask_set(indio_dev->buffer, 0); + iio_scan_mask_set(indio_dev->buffer, 1); ret = ad5933_setup(st); if (ret) diff --git a/trunk/drivers/staging/iio/industrialio-buffer.c b/trunk/drivers/staging/iio/industrialio-buffer.c index 552e33f74769..b46ae6a2424f 100644 --- a/trunk/drivers/staging/iio/industrialio-buffer.c +++ b/trunk/drivers/staging/iio/industrialio-buffer.c @@ -85,9 +85,10 @@ void iio_chrdev_buffer_release(struct iio_dev *indio_dev) rb->access->unmark_in_use(rb); } -void iio_buffer_init(struct iio_buffer *buffer) +void iio_buffer_init(struct iio_buffer *buffer, struct iio_dev *indio_dev) { INIT_LIST_HEAD(&buffer->demux_list); + buffer->indio_dev = indio_dev; init_waitqueue_head(&buffer->pollq); } EXPORT_SYMBOL(iio_buffer_init); @@ -157,7 +158,7 @@ static ssize_t iio_scan_el_store(struct device *dev, ret = -EBUSY; goto error_ret; } - ret = iio_scan_mask_query(indio_dev, buffer, this_attr->address); + ret = iio_scan_mask_query(buffer, this_attr->address); if (ret < 0) goto error_ret; if (!state && ret) { @@ -165,7 +166,7 @@ static ssize_t iio_scan_el_store(struct device *dev, if (ret) goto error_ret; } else if (state && !ret) { - ret = iio_scan_mask_set(indio_dev, buffer, this_attr->address); + ret = iio_scan_mask_set(buffer, this_attr->address); if (ret) goto error_ret; } @@ -577,9 +578,9 @@ EXPORT_SYMBOL(iio_sw_buffer_preenable); * @buffer: the buffer whose scan mask we are interested in * @bit: the bit to be set. **/ -int iio_scan_mask_set(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) +int iio_scan_mask_set(struct iio_buffer *buffer, int bit) { + struct iio_dev *indio_dev = buffer->indio_dev; unsigned long *mask; unsigned long *trialmask; @@ -614,9 +615,9 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, }; EXPORT_SYMBOL_GPL(iio_scan_mask_set); -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) +int iio_scan_mask_query(struct iio_buffer *buffer, int bit) { + struct iio_dev *indio_dev = buffer->indio_dev; long *mask; if (bit > indio_dev->masklength) diff --git a/trunk/drivers/staging/iio/kfifo_buf.c b/trunk/drivers/staging/iio/kfifo_buf.c index d8867abd0a84..fb3b7ae978d1 100644 --- a/trunk/drivers/staging/iio/kfifo_buf.c +++ b/trunk/drivers/staging/iio/kfifo_buf.c @@ -96,7 +96,7 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) if (!kf) return NULL; kf->update_needed = true; - iio_buffer_init(&kf->buffer); + iio_buffer_init(&kf->buffer, indio_dev); kf->buffer.attrs = &iio_kfifo_attribute_group; __iio_init_kfifo(kf); diff --git a/trunk/drivers/staging/iio/ring_sw.c b/trunk/drivers/staging/iio/ring_sw.c index a541a73a2105..98fe81932047 100644 --- a/trunk/drivers/staging/iio/ring_sw.c +++ b/trunk/drivers/staging/iio/ring_sw.c @@ -23,6 +23,7 @@ * @data: the ring buffer memory * @read_p: read pointer (oldest available) * @write_p: write pointer + * @last_written_p: read pointer (newest available) * @half_p: half buffer length behind write_p (event generation) * @use_count: reference count to prevent resizing when in use * @update_needed: flag to indicated change in size requested @@ -36,6 +37,7 @@ struct iio_sw_ring_buffer { unsigned char *data; unsigned char *read_p; unsigned char *write_p; + unsigned char *last_written_p; /* used to act as a point at which to signal an event */ unsigned char *half_p; int use_count; @@ -54,6 +56,7 @@ static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring, ring->data = kmalloc(length*ring->buf.bytes_per_datum, GFP_ATOMIC); ring->read_p = NULL; ring->write_p = NULL; + ring->last_written_p = NULL; ring->half_p = NULL; return ring->data ? 0 : -ENOMEM; } @@ -112,6 +115,7 @@ static int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring, * Always valid as either points to latest or second latest value. * Before this runs it is null and read attempts fail with -EAGAIN. */ + ring->last_written_p = ring->write_p; barrier(); /* temp_ptr used to ensure we never have an invalid pointer * it may be slightly lagging, but never invalid @@ -301,6 +305,34 @@ static int iio_store_to_sw_rb(struct iio_buffer *r, return iio_store_to_sw_ring(ring, data, timestamp); } +static int iio_read_last_from_sw_ring(struct iio_sw_ring_buffer *ring, + unsigned char *data) +{ + unsigned char *last_written_p_copy; + + iio_mark_sw_rb_in_use(&ring->buf); +again: + barrier(); + last_written_p_copy = ring->last_written_p; + barrier(); /*unnessecary? */ + /* Check there is anything here */ + if (last_written_p_copy == NULL) + return -EAGAIN; + memcpy(data, last_written_p_copy, ring->buf.bytes_per_datum); + + if (unlikely(ring->last_written_p != last_written_p_copy)) + goto again; + + iio_unmark_sw_rb_in_use(&ring->buf); + return 0; +} + +static int iio_read_last_from_sw_rb(struct iio_buffer *r, + unsigned char *data) +{ + return iio_read_last_from_sw_ring(iio_to_sw_ring(r), data); +} + static int iio_request_update_sw_rb(struct iio_buffer *r) { int ret = 0; @@ -385,7 +417,7 @@ struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev) return NULL; ring->update_needed = true; buf = &ring->buf; - iio_buffer_init(buf); + iio_buffer_init(buf, indio_dev); __iio_init_sw_ring_buffer(ring); buf->attrs = &iio_ring_attribute_group; @@ -403,6 +435,7 @@ const struct iio_buffer_access_funcs ring_sw_access_funcs = { .mark_in_use = &iio_mark_sw_rb_in_use, .unmark_in_use = &iio_unmark_sw_rb_in_use, .store_to = &iio_store_to_sw_rb, + .read_last = &iio_read_last_from_sw_rb, .read_first_n = &iio_read_first_n_sw_rb, .mark_param_change = &iio_mark_update_needed_sw_rb, .request_update = &iio_request_update_sw_rb, diff --git a/trunk/drivers/staging/iio/types.h b/trunk/drivers/staging/iio/types.h index f1f5ca2aa385..b7d26474ad06 100644 --- a/trunk/drivers/staging/iio/types.h +++ b/trunk/drivers/staging/iio/types.h @@ -35,7 +35,7 @@ enum iio_modifier { IIO_MOD_Y, IIO_MOD_Z, IIO_MOD_X_AND_Y, - IIO_MOD_X_ANX_Z, + IIO_MOD_X_AND_Z, IIO_MOD_Y_AND_Z, IIO_MOD_X_AND_Y_AND_Z, IIO_MOD_X_OR_Y,