From 5d65d92045cb7d3b2c45020c0e62d6d1c1d34f37 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 15 Sep 2013 17:50:00 +0100 Subject: iio: iio_push_to_buffers(): Change type of 'data' to const void * Change the type of the 'data' parameter for iio_push_to_buffers() from 'u8 *' to 'const void *'. Drivers typically use the correct type (e.g. __be16 *) for their data buffer. When passing the buffer to iio_push_to_buffers() it needs to be cast to 'u8 *' for the compiler to not complain (and also having to add __force if we want to keep sparse happy as well). Since the buffer implementation should not care about the data layout (except the size of one sample) using a void pointer is the correct thing to do. Also make it const as the buffer implementations are not supposed to modify it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux/iio/buffer.h') diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 2bac0eb8948d..e5507e999ed1 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -36,7 +36,7 @@ struct iio_buffer; * any of them not existing. **/ struct iio_buffer_access_funcs { - int (*store_to)(struct iio_buffer *buffer, u8 *data); + int (*store_to)(struct iio_buffer *buffer, const void *data); int (*read_first_n)(struct iio_buffer *buffer, size_t n, char __user *buf); @@ -81,7 +81,7 @@ struct iio_buffer { bool stufftoread; const struct attribute_group *attrs; struct list_head demux_list; - unsigned char *demux_bounce; + void *demux_bounce; struct list_head buffer_list; }; @@ -120,7 +120,7 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, * @indio_dev: iio_dev structure for device. * @data: Full scan. */ -int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data); +int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data); int iio_update_demux(struct iio_dev *indio_dev); -- cgit v1.2.2 From d2c3d072c4aded65f0632223cc0d3a8a2e577b3a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 19 Sep 2013 13:59:00 +0100 Subject: iio: Add iio_push_buffers_with_timestamp() helper Drivers using software buffers often store the timestamp in their data buffer before calling iio_push_to_buffers() with that data buffer. Storing the timestamp in the buffer usually involves some ugly pointer arithmetic. This patch adds a new helper function called iio_push_buffers_with_timestamp() which is similar to iio_push_to_buffers but takes an additional timestamp parameter. The function will help to hide to uglyness in one central place instead of exposing it in every driver. If timestamps are enabled for the IIO device iio_push_buffers_with_timestamp() will store the timestamp as the last element in buffer, before passing the buffer on to iio_push_buffers(). The buffer needs large enough to hold the timestamp in this case. If timestamps are disabled iio_push_buffers_with_timestamp() will behave just like iio_push_buffers(). Signed-off-by: Lars-Peter Clausen Cc: Oleksandr Kravchenko Cc: Josh Wu Cc: Denis Ciocca Cc: Manuel Stahl Cc: Ge Gao Cc: Peter Meerwald Cc: Jacek Anaszewski Cc: Fabio Estevam Cc: Marek Vasut Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'include/linux/iio/buffer.h') diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index e5507e999ed1..a1124bdc4cac 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -122,6 +122,31 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, */ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data); +/* + * iio_push_to_buffers_with_timestamp() - push data and timestamp to buffers + * @indio_dev: iio_dev structure for device. + * @data: sample data + * @timestamp: timestamp for the sample data + * + * Pushes data to the IIO device's buffers. If timestamps are enabled for the + * device the function will store the supplied timestamp as the last element in + * the sample data buffer before pushing it to the device buffers. The sample + * data buffer needs to be large enough to hold the additional timestamp + * (usually the buffer should be indio->scan_bytes bytes large). + * + * Returns 0 on success, a negative error code otherwise. + */ +static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev, + void *data, int64_t timestamp) +{ + if (indio_dev->scan_timestamp) { + size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1; + ((int64_t *)data)[ts_offset] = timestamp; + } + + return iio_push_to_buffers(indio_dev, data); +} + int iio_update_demux(struct iio_dev *indio_dev); /** -- cgit v1.2.2 From 9e69c935fad9fd5f0550c51e3bd251cd30033136 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 4 Oct 2013 12:06:00 +0100 Subject: iio: Add reference counting for buffers Since the buffer is accessed by userspace we can not just free the buffers memory once we are done with it in kernel space. There might still be open file descriptors and userspace still might be accessing the buffer. This patch adds support for reference counting to the IIO buffers. When a buffer is created and initialized its initial reference count is set to 1. Instead of freeing the memory of the buffer the buffer's _free() function will drop that reference again. But only after the last reference to the buffer has been dropped the buffer the buffer's memory will be freed. The IIO device will take a reference to its primary buffer. The patch adds a small helper function for this called iio_device_attach_buffer() which will get a reference to the buffer and assign the buffer to the IIO device. This function must be used instead of assigning the buffer to the device by hand. The reference is only dropped once the IIO device is freed and we can be sure that there are no more open file handles. A reference to a buffer will also be taken whenever the buffer is active to avoid the buffer being freed while data is still being send to it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'include/linux/iio/buffer.h') diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index a1124bdc4cac..6e428d96d570 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -11,6 +11,7 @@ #define _IIO_BUFFER_GENERIC_H_ #include #include +#include #ifdef CONFIG_IIO_BUFFER @@ -26,6 +27,8 @@ struct iio_buffer; * @set_bytes_per_datum:set number of bytes per datum * @get_length: get number of datums in buffer * @set_length: set number of datums in buffer + * @release: called when the last reference to the buffer is dropped, + * should free all resources allocated by the buffer. * * The purpose of this structure is to make the buffer element * modular as event for a given driver, different usecases may require @@ -47,6 +50,8 @@ struct iio_buffer_access_funcs { int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); int (*get_length)(struct iio_buffer *buffer); int (*set_length)(struct iio_buffer *buffer, int length); + + void (*release)(struct iio_buffer *buffer); }; /** @@ -67,6 +72,7 @@ struct iio_buffer_access_funcs { * @demux_list: [INTERN] list of operations required to demux the scan. * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. * @buffer_list: [INTERN] entry in the devices list of current buffers. + * @ref: [INTERN] reference count of the buffer. */ struct iio_buffer { int length; @@ -83,6 +89,7 @@ struct iio_buffer { struct list_head demux_list; void *demux_bounce; struct list_head buffer_list; + struct kref ref; }; /** @@ -204,6 +211,24 @@ int iio_sw_buffer_preenable(struct iio_dev *indio_dev); bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, const unsigned long *mask); +struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer); +void iio_buffer_put(struct iio_buffer *buffer); + +/** + * iio_device_attach_buffer - Attach a buffer to a IIO device + * @indio_dev: The device the buffer should be attached to + * @buffer: The buffer to attach to the device + * + * This function attaches a buffer to a IIO device. The buffer stays attached to + * the device until the device is freed. The function should only be called at + * most once per device. + */ +static inline void iio_device_attach_buffer(struct iio_dev *indio_dev, + struct iio_buffer *buffer) +{ + indio_dev->buffer = iio_buffer_get(buffer); +} + #else /* CONFIG_IIO_BUFFER */ static inline int iio_buffer_register(struct iio_dev *indio_dev, @@ -216,6 +241,9 @@ static inline int iio_buffer_register(struct iio_dev *indio_dev, static inline void iio_buffer_unregister(struct iio_dev *indio_dev) {} +static inline void iio_buffer_get(struct iio_buffer *buffer) {} +static inline void iio_buffer_put(struct iio_buffer *buffer) {} + #endif /* CONFIG_IIO_BUFFER */ #endif /* _IIO_BUFFER_GENERIC_H_ */ -- cgit v1.2.2 From bf741c08af194ed0448799ff2690c8dd3da709e5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Oct 2013 17:49:00 +0100 Subject: iio: Remove unused iio_sw_buffer_preenable() The functionality implemented by iio_sw_buffer_preenable() is now done directly in the IIO core and previous users of iio_sw_buffer_preenable() have all been updated to not use it anymore. It is unused now and can be remove. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux/iio/buffer.h') diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 6e428d96d570..15607b45221a 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -206,8 +206,6 @@ ssize_t iio_buffer_show_enable(struct device *dev, iio_buffer_show_enable, \ iio_buffer_store_enable) -int iio_sw_buffer_preenable(struct iio_dev *indio_dev); - bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, const unsigned long *mask); -- cgit v1.2.2