aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/iio
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-10-04 07:06:00 -0400
committerJonathan Cameron <jic23@kernel.org>2013-10-12 07:04:01 -0400
commit9e69c935fad9fd5f0550c51e3bd251cd30033136 (patch)
tree7900ed537ab31df1bc95e210fd99f187cd6efbc8 /include/linux/iio
parent2b6d598bc9043f51d2092d10392a6e3c161cdff7 (diff)
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 <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'include/linux/iio')
-rw-r--r--include/linux/iio/buffer.h28
1 files changed, 28 insertions, 0 deletions
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 @@
11#define _IIO_BUFFER_GENERIC_H_ 11#define _IIO_BUFFER_GENERIC_H_
12#include <linux/sysfs.h> 12#include <linux/sysfs.h>
13#include <linux/iio/iio.h> 13#include <linux/iio/iio.h>
14#include <linux/kref.h>
14 15
15#ifdef CONFIG_IIO_BUFFER 16#ifdef CONFIG_IIO_BUFFER
16 17
@@ -26,6 +27,8 @@ struct iio_buffer;
26 * @set_bytes_per_datum:set number of bytes per datum 27 * @set_bytes_per_datum:set number of bytes per datum
27 * @get_length: get number of datums in buffer 28 * @get_length: get number of datums in buffer
28 * @set_length: set number of datums in buffer 29 * @set_length: set number of datums in buffer
30 * @release: called when the last reference to the buffer is dropped,
31 * should free all resources allocated by the buffer.
29 * 32 *
30 * The purpose of this structure is to make the buffer element 33 * The purpose of this structure is to make the buffer element
31 * modular as event for a given driver, different usecases may require 34 * modular as event for a given driver, different usecases may require
@@ -47,6 +50,8 @@ struct iio_buffer_access_funcs {
47 int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); 50 int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
48 int (*get_length)(struct iio_buffer *buffer); 51 int (*get_length)(struct iio_buffer *buffer);
49 int (*set_length)(struct iio_buffer *buffer, int length); 52 int (*set_length)(struct iio_buffer *buffer, int length);
53
54 void (*release)(struct iio_buffer *buffer);
50}; 55};
51 56
52/** 57/**
@@ -67,6 +72,7 @@ struct iio_buffer_access_funcs {
67 * @demux_list: [INTERN] list of operations required to demux the scan. 72 * @demux_list: [INTERN] list of operations required to demux the scan.
68 * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. 73 * @demux_bounce: [INTERN] buffer for doing gather from incoming scan.
69 * @buffer_list: [INTERN] entry in the devices list of current buffers. 74 * @buffer_list: [INTERN] entry in the devices list of current buffers.
75 * @ref: [INTERN] reference count of the buffer.
70 */ 76 */
71struct iio_buffer { 77struct iio_buffer {
72 int length; 78 int length;
@@ -83,6 +89,7 @@ struct iio_buffer {
83 struct list_head demux_list; 89 struct list_head demux_list;
84 void *demux_bounce; 90 void *demux_bounce;
85 struct list_head buffer_list; 91 struct list_head buffer_list;
92 struct kref ref;
86}; 93};
87 94
88/** 95/**
@@ -204,6 +211,24 @@ int iio_sw_buffer_preenable(struct iio_dev *indio_dev);
204bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, 211bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
205 const unsigned long *mask); 212 const unsigned long *mask);
206 213
214struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer);
215void iio_buffer_put(struct iio_buffer *buffer);
216
217/**
218 * iio_device_attach_buffer - Attach a buffer to a IIO device
219 * @indio_dev: The device the buffer should be attached to
220 * @buffer: The buffer to attach to the device
221 *
222 * This function attaches a buffer to a IIO device. The buffer stays attached to
223 * the device until the device is freed. The function should only be called at
224 * most once per device.
225 */
226static inline void iio_device_attach_buffer(struct iio_dev *indio_dev,
227 struct iio_buffer *buffer)
228{
229 indio_dev->buffer = iio_buffer_get(buffer);
230}
231
207#else /* CONFIG_IIO_BUFFER */ 232#else /* CONFIG_IIO_BUFFER */
208 233
209static inline int iio_buffer_register(struct iio_dev *indio_dev, 234static 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,
216static inline void iio_buffer_unregister(struct iio_dev *indio_dev) 241static inline void iio_buffer_unregister(struct iio_dev *indio_dev)
217{} 242{}
218 243
244static inline void iio_buffer_get(struct iio_buffer *buffer) {}
245static inline void iio_buffer_put(struct iio_buffer *buffer) {}
246
219#endif /* CONFIG_IIO_BUFFER */ 247#endif /* CONFIG_IIO_BUFFER */
220 248
221#endif /* _IIO_BUFFER_GENERIC_H_ */ 249#endif /* _IIO_BUFFER_GENERIC_H_ */