diff options
-rw-r--r-- | drivers/iio/buffer_cb.c | 21 | ||||
-rw-r--r-- | drivers/iio/industrialio-buffer.c | 66 | ||||
-rw-r--r-- | drivers/iio/industrialio-core.c | 3 | ||||
-rw-r--r-- | drivers/iio/industrialio-triggered-buffer.c | 7 | ||||
-rw-r--r-- | drivers/iio/kfifo_buf.c | 8 | ||||
-rw-r--r-- | drivers/staging/iio/accel/lis3l02dq_ring.c | 2 | ||||
-rw-r--r-- | drivers/staging/iio/accel/sca3000_ring.c | 13 | ||||
-rw-r--r-- | drivers/staging/iio/iio_simple_dummy_buffer.c | 2 | ||||
-rw-r--r-- | drivers/staging/iio/impedance-analyzer/ad5933.c | 8 | ||||
-rw-r--r-- | drivers/staging/iio/meter/ade7758_ring.c | 7 | ||||
-rw-r--r-- | include/linux/iio/buffer.h | 28 |
11 files changed, 141 insertions, 24 deletions
diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c index 841fec1e78b2..2d9c6f8c06db 100644 --- a/drivers/iio/buffer_cb.c +++ b/drivers/iio/buffer_cb.c | |||
@@ -12,17 +12,27 @@ struct iio_cb_buffer { | |||
12 | struct iio_channel *channels; | 12 | struct iio_channel *channels; |
13 | }; | 13 | }; |
14 | 14 | ||
15 | static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data) | 15 | static struct iio_cb_buffer *buffer_to_cb_buffer(struct iio_buffer *buffer) |
16 | { | 16 | { |
17 | struct iio_cb_buffer *cb_buff = container_of(buffer, | 17 | return container_of(buffer, struct iio_cb_buffer, buffer); |
18 | struct iio_cb_buffer, | 18 | } |
19 | buffer); | ||
20 | 19 | ||
20 | static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data) | ||
21 | { | ||
22 | struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer); | ||
21 | return cb_buff->cb(data, cb_buff->private); | 23 | return cb_buff->cb(data, cb_buff->private); |
22 | } | 24 | } |
23 | 25 | ||
26 | static void iio_buffer_cb_release(struct iio_buffer *buffer) | ||
27 | { | ||
28 | struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer); | ||
29 | kfree(cb_buff->buffer.scan_mask); | ||
30 | kfree(cb_buff); | ||
31 | } | ||
32 | |||
24 | static const struct iio_buffer_access_funcs iio_cb_access = { | 33 | static const struct iio_buffer_access_funcs iio_cb_access = { |
25 | .store_to = &iio_buffer_cb_store_to, | 34 | .store_to = &iio_buffer_cb_store_to, |
35 | .release = &iio_buffer_cb_release, | ||
26 | }; | 36 | }; |
27 | 37 | ||
28 | struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, | 38 | struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, |
@@ -104,9 +114,8 @@ EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb); | |||
104 | 114 | ||
105 | void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff) | 115 | void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff) |
106 | { | 116 | { |
107 | kfree(cb_buff->buffer.scan_mask); | ||
108 | iio_channel_release_all(cb_buff->channels); | 117 | iio_channel_release_all(cb_buff->channels); |
109 | kfree(cb_buff); | 118 | iio_buffer_put(&cb_buff->buffer); |
110 | } | 119 | } |
111 | EXPORT_SYMBOL_GPL(iio_channel_release_all_cb); | 120 | EXPORT_SYMBOL_GPL(iio_channel_release_all_cb); |
112 | 121 | ||
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index e9f389b9da69..36c39dcad850 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c | |||
@@ -74,6 +74,7 @@ void iio_buffer_init(struct iio_buffer *buffer) | |||
74 | INIT_LIST_HEAD(&buffer->demux_list); | 74 | INIT_LIST_HEAD(&buffer->demux_list); |
75 | INIT_LIST_HEAD(&buffer->buffer_list); | 75 | INIT_LIST_HEAD(&buffer->buffer_list); |
76 | init_waitqueue_head(&buffer->pollq); | 76 | init_waitqueue_head(&buffer->pollq); |
77 | kref_init(&buffer->ref); | ||
77 | } | 78 | } |
78 | EXPORT_SYMBOL(iio_buffer_init); | 79 | EXPORT_SYMBOL(iio_buffer_init); |
79 | 80 | ||
@@ -454,6 +455,19 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, | |||
454 | return bytes; | 455 | return bytes; |
455 | } | 456 | } |
456 | 457 | ||
458 | static void iio_buffer_activate(struct iio_dev *indio_dev, | ||
459 | struct iio_buffer *buffer) | ||
460 | { | ||
461 | iio_buffer_get(buffer); | ||
462 | list_add(&buffer->buffer_list, &indio_dev->buffer_list); | ||
463 | } | ||
464 | |||
465 | static void iio_buffer_deactivate(struct iio_buffer *buffer) | ||
466 | { | ||
467 | list_del_init(&buffer->buffer_list); | ||
468 | iio_buffer_put(buffer); | ||
469 | } | ||
470 | |||
457 | void iio_disable_all_buffers(struct iio_dev *indio_dev) | 471 | void iio_disable_all_buffers(struct iio_dev *indio_dev) |
458 | { | 472 | { |
459 | struct iio_buffer *buffer, *_buffer; | 473 | struct iio_buffer *buffer, *_buffer; |
@@ -466,7 +480,7 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev) | |||
466 | 480 | ||
467 | list_for_each_entry_safe(buffer, _buffer, | 481 | list_for_each_entry_safe(buffer, _buffer, |
468 | &indio_dev->buffer_list, buffer_list) | 482 | &indio_dev->buffer_list, buffer_list) |
469 | list_del_init(&buffer->buffer_list); | 483 | iio_buffer_deactivate(buffer); |
470 | 484 | ||
471 | indio_dev->currentmode = INDIO_DIRECT_MODE; | 485 | indio_dev->currentmode = INDIO_DIRECT_MODE; |
472 | if (indio_dev->setup_ops->postdisable) | 486 | if (indio_dev->setup_ops->postdisable) |
@@ -503,9 +517,9 @@ int iio_update_buffers(struct iio_dev *indio_dev, | |||
503 | indio_dev->active_scan_mask = NULL; | 517 | indio_dev->active_scan_mask = NULL; |
504 | 518 | ||
505 | if (remove_buffer) | 519 | if (remove_buffer) |
506 | list_del_init(&remove_buffer->buffer_list); | 520 | iio_buffer_deactivate(remove_buffer); |
507 | if (insert_buffer) | 521 | if (insert_buffer) |
508 | list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list); | 522 | iio_buffer_activate(indio_dev, insert_buffer); |
509 | 523 | ||
510 | /* If no buffers in list, we are done */ | 524 | /* If no buffers in list, we are done */ |
511 | if (list_empty(&indio_dev->buffer_list)) { | 525 | if (list_empty(&indio_dev->buffer_list)) { |
@@ -540,7 +554,7 @@ int iio_update_buffers(struct iio_dev *indio_dev, | |||
540 | * Roll back. | 554 | * Roll back. |
541 | * Note can only occur when adding a buffer. | 555 | * Note can only occur when adding a buffer. |
542 | */ | 556 | */ |
543 | list_del_init(&insert_buffer->buffer_list); | 557 | iio_buffer_deactivate(insert_buffer); |
544 | if (old_mask) { | 558 | if (old_mask) { |
545 | indio_dev->active_scan_mask = old_mask; | 559 | indio_dev->active_scan_mask = old_mask; |
546 | success = -EINVAL; | 560 | success = -EINVAL; |
@@ -631,7 +645,7 @@ error_run_postdisable: | |||
631 | error_remove_inserted: | 645 | error_remove_inserted: |
632 | 646 | ||
633 | if (insert_buffer) | 647 | if (insert_buffer) |
634 | list_del_init(&insert_buffer->buffer_list); | 648 | iio_buffer_deactivate(insert_buffer); |
635 | indio_dev->active_scan_mask = old_mask; | 649 | indio_dev->active_scan_mask = old_mask; |
636 | kfree(compound_mask); | 650 | kfree(compound_mask); |
637 | error_ret: | 651 | error_ret: |
@@ -952,3 +966,45 @@ error_clear_mux_table: | |||
952 | return ret; | 966 | return ret; |
953 | } | 967 | } |
954 | EXPORT_SYMBOL_GPL(iio_update_demux); | 968 | EXPORT_SYMBOL_GPL(iio_update_demux); |
969 | |||
970 | /** | ||
971 | * iio_buffer_release() - Free a buffer's resources | ||
972 | * @ref: Pointer to the kref embedded in the iio_buffer struct | ||
973 | * | ||
974 | * This function is called when the last reference to the buffer has been | ||
975 | * dropped. It will typically free all resources allocated by the buffer. Do not | ||
976 | * call this function manually, always use iio_buffer_put() when done using a | ||
977 | * buffer. | ||
978 | */ | ||
979 | static void iio_buffer_release(struct kref *ref) | ||
980 | { | ||
981 | struct iio_buffer *buffer = container_of(ref, struct iio_buffer, ref); | ||
982 | |||
983 | buffer->access->release(buffer); | ||
984 | } | ||
985 | |||
986 | /** | ||
987 | * iio_buffer_get() - Grab a reference to the buffer | ||
988 | * @buffer: The buffer to grab a reference for, may be NULL | ||
989 | * | ||
990 | * Returns the pointer to the buffer that was passed into the function. | ||
991 | */ | ||
992 | struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer) | ||
993 | { | ||
994 | if (buffer) | ||
995 | kref_get(&buffer->ref); | ||
996 | |||
997 | return buffer; | ||
998 | } | ||
999 | EXPORT_SYMBOL_GPL(iio_buffer_get); | ||
1000 | |||
1001 | /** | ||
1002 | * iio_buffer_put() - Release the reference to the buffer | ||
1003 | * @buffer: The buffer to release the reference for, may be NULL | ||
1004 | */ | ||
1005 | void iio_buffer_put(struct iio_buffer *buffer) | ||
1006 | { | ||
1007 | if (buffer) | ||
1008 | kref_put(&buffer->ref, iio_buffer_release); | ||
1009 | } | ||
1010 | EXPORT_SYMBOL_GPL(iio_buffer_put); | ||
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index ecf58963ac24..f939bad31ca1 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "iio_core_trigger.h" | 28 | #include "iio_core_trigger.h" |
29 | #include <linux/iio/sysfs.h> | 29 | #include <linux/iio/sysfs.h> |
30 | #include <linux/iio/events.h> | 30 | #include <linux/iio/events.h> |
31 | #include <linux/iio/buffer.h> | ||
31 | 32 | ||
32 | /* IDA to assign each registered device a unique id */ | 33 | /* IDA to assign each registered device a unique id */ |
33 | static DEFINE_IDA(iio_ida); | 34 | static DEFINE_IDA(iio_ida); |
@@ -895,6 +896,8 @@ static void iio_dev_release(struct device *device) | |||
895 | iio_device_unregister_eventset(indio_dev); | 896 | iio_device_unregister_eventset(indio_dev); |
896 | iio_device_unregister_sysfs(indio_dev); | 897 | iio_device_unregister_sysfs(indio_dev); |
897 | 898 | ||
899 | iio_buffer_put(indio_dev->buffer); | ||
900 | |||
898 | ida_simple_remove(&iio_ida, indio_dev->id); | 901 | ida_simple_remove(&iio_ida, indio_dev->id); |
899 | kfree(indio_dev); | 902 | kfree(indio_dev); |
900 | } | 903 | } |
diff --git a/drivers/iio/industrialio-triggered-buffer.c b/drivers/iio/industrialio-triggered-buffer.c index 46c619b0d8c5..c1cb1f94fe2e 100644 --- a/drivers/iio/industrialio-triggered-buffer.c +++ b/drivers/iio/industrialio-triggered-buffer.c | |||
@@ -47,14 +47,17 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev, | |||
47 | irqreturn_t (*pollfunc_th)(int irq, void *p), | 47 | irqreturn_t (*pollfunc_th)(int irq, void *p), |
48 | const struct iio_buffer_setup_ops *setup_ops) | 48 | const struct iio_buffer_setup_ops *setup_ops) |
49 | { | 49 | { |
50 | struct iio_buffer *buffer; | ||
50 | int ret; | 51 | int ret; |
51 | 52 | ||
52 | indio_dev->buffer = iio_kfifo_allocate(indio_dev); | 53 | buffer = iio_kfifo_allocate(indio_dev); |
53 | if (!indio_dev->buffer) { | 54 | if (!buffer) { |
54 | ret = -ENOMEM; | 55 | ret = -ENOMEM; |
55 | goto error_ret; | 56 | goto error_ret; |
56 | } | 57 | } |
57 | 58 | ||
59 | iio_device_attach_buffer(indio_dev, buffer); | ||
60 | |||
58 | indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh, | 61 | indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh, |
59 | pollfunc_th, | 62 | pollfunc_th, |
60 | IRQF_ONESHOT, | 63 | IRQF_ONESHOT, |
diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 538d4616e48f..b4ac55a29fc4 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c | |||
@@ -130,6 +130,11 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, | |||
130 | return copied; | 130 | return copied; |
131 | } | 131 | } |
132 | 132 | ||
133 | static void iio_kfifo_buffer_release(struct iio_buffer *buffer) | ||
134 | { | ||
135 | kfree(iio_to_kfifo(buffer)); | ||
136 | } | ||
137 | |||
133 | static const struct iio_buffer_access_funcs kfifo_access_funcs = { | 138 | static const struct iio_buffer_access_funcs kfifo_access_funcs = { |
134 | .store_to = &iio_store_to_kfifo, | 139 | .store_to = &iio_store_to_kfifo, |
135 | .read_first_n = &iio_read_first_n_kfifo, | 140 | .read_first_n = &iio_read_first_n_kfifo, |
@@ -138,6 +143,7 @@ static const struct iio_buffer_access_funcs kfifo_access_funcs = { | |||
138 | .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, | 143 | .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, |
139 | .get_length = &iio_get_length_kfifo, | 144 | .get_length = &iio_get_length_kfifo, |
140 | .set_length = &iio_set_length_kfifo, | 145 | .set_length = &iio_set_length_kfifo, |
146 | .release = &iio_kfifo_buffer_release, | ||
141 | }; | 147 | }; |
142 | 148 | ||
143 | struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) | 149 | struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) |
@@ -158,7 +164,7 @@ EXPORT_SYMBOL(iio_kfifo_allocate); | |||
158 | 164 | ||
159 | void iio_kfifo_free(struct iio_buffer *r) | 165 | void iio_kfifo_free(struct iio_buffer *r) |
160 | { | 166 | { |
161 | kfree(iio_to_kfifo(r)); | 167 | iio_buffer_put(r); |
162 | } | 168 | } |
163 | EXPORT_SYMBOL(iio_kfifo_free); | 169 | EXPORT_SYMBOL(iio_kfifo_free); |
164 | 170 | ||
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index ed7de471e3f3..2d559ba353d2 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c | |||
@@ -396,7 +396,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev) | |||
396 | if (!buffer) | 396 | if (!buffer) |
397 | return -ENOMEM; | 397 | return -ENOMEM; |
398 | 398 | ||
399 | indio_dev->buffer = buffer; | 399 | iio_device_attach_buffer(indio_dev, buffer); |
400 | 400 | ||
401 | buffer->scan_timestamp = true; | 401 | buffer->scan_timestamp = true; |
402 | indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops; | 402 | indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops; |
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 0f2ee3373d9a..4a27beb1451a 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c | |||
@@ -265,7 +265,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev) | |||
265 | return buf; | 265 | return buf; |
266 | } | 266 | } |
267 | 267 | ||
268 | static inline void sca3000_rb_free(struct iio_buffer *r) | 268 | static void sca3000_ring_release(struct iio_buffer *r) |
269 | { | 269 | { |
270 | kfree(iio_to_hw_buf(r)); | 270 | kfree(iio_to_hw_buf(r)); |
271 | } | 271 | } |
@@ -274,23 +274,28 @@ static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = { | |||
274 | .read_first_n = &sca3000_read_first_n_hw_rb, | 274 | .read_first_n = &sca3000_read_first_n_hw_rb, |
275 | .get_length = &sca3000_ring_get_length, | 275 | .get_length = &sca3000_ring_get_length, |
276 | .get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum, | 276 | .get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum, |
277 | .release = sca3000_ring_release, | ||
277 | }; | 278 | }; |
278 | 279 | ||
279 | int sca3000_configure_ring(struct iio_dev *indio_dev) | 280 | int sca3000_configure_ring(struct iio_dev *indio_dev) |
280 | { | 281 | { |
281 | indio_dev->buffer = sca3000_rb_allocate(indio_dev); | 282 | struct iio_buffer *buffer; |
282 | if (indio_dev->buffer == NULL) | 283 | |
284 | buffer = sca3000_rb_allocate(indio_dev); | ||
285 | if (buffer == NULL) | ||
283 | return -ENOMEM; | 286 | return -ENOMEM; |
284 | indio_dev->modes |= INDIO_BUFFER_HARDWARE; | 287 | indio_dev->modes |= INDIO_BUFFER_HARDWARE; |
285 | 288 | ||
286 | indio_dev->buffer->access = &sca3000_ring_access_funcs; | 289 | indio_dev->buffer->access = &sca3000_ring_access_funcs; |
287 | 290 | ||
291 | iio_device_attach_buffer(indio_dev, buffer); | ||
292 | |||
288 | return 0; | 293 | return 0; |
289 | } | 294 | } |
290 | 295 | ||
291 | void sca3000_unconfigure_ring(struct iio_dev *indio_dev) | 296 | void sca3000_unconfigure_ring(struct iio_dev *indio_dev) |
292 | { | 297 | { |
293 | sca3000_rb_free(indio_dev->buffer); | 298 | iio_buffer_put(indio_dev->buffer); |
294 | } | 299 | } |
295 | 300 | ||
296 | static inline | 301 | static inline |
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index 09c93ac7351a..2612e87fbcb4 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c | |||
@@ -135,7 +135,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev, | |||
135 | goto error_ret; | 135 | goto error_ret; |
136 | } | 136 | } |
137 | 137 | ||
138 | indio_dev->buffer = buffer; | 138 | iio_device_attach_buffer(indio_dev, buffer); |
139 | 139 | ||
140 | /* Enable timestamps by default */ | 140 | /* Enable timestamps by default */ |
141 | buffer->scan_timestamp = true; | 141 | buffer->scan_timestamp = true; |
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 712f3c22ce64..f5701159bf36 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c | |||
@@ -630,10 +630,14 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = { | |||
630 | 630 | ||
631 | static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) | 631 | static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) |
632 | { | 632 | { |
633 | indio_dev->buffer = iio_kfifo_allocate(indio_dev); | 633 | struct iio_buffer *buffer; |
634 | if (!indio_dev->buffer) | 634 | |
635 | buffer = iio_kfifo_allocate(indio_dev); | ||
636 | if (buffer) | ||
635 | return -ENOMEM; | 637 | return -ENOMEM; |
636 | 638 | ||
639 | iio_device_attach_buffer(indio_dev, buffer); | ||
640 | |||
637 | /* Ring buffer functions - here trigger setup related */ | 641 | /* Ring buffer functions - here trigger setup related */ |
638 | indio_dev->setup_ops = &ad5933_ring_setup_ops; | 642 | indio_dev->setup_ops = &ad5933_ring_setup_ops; |
639 | 643 | ||
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 4080995c99b6..7a448ffaeb14 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c | |||
@@ -121,14 +121,17 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev) | |||
121 | int ade7758_configure_ring(struct iio_dev *indio_dev) | 121 | int ade7758_configure_ring(struct iio_dev *indio_dev) |
122 | { | 122 | { |
123 | struct ade7758_state *st = iio_priv(indio_dev); | 123 | struct ade7758_state *st = iio_priv(indio_dev); |
124 | struct iio_buffer *buffer; | ||
124 | int ret = 0; | 125 | int ret = 0; |
125 | 126 | ||
126 | indio_dev->buffer = iio_kfifo_allocate(indio_dev); | 127 | buffer = iio_kfifo_allocate(indio_dev); |
127 | if (!indio_dev->buffer) { | 128 | if (!buffer) { |
128 | ret = -ENOMEM; | 129 | ret = -ENOMEM; |
129 | return ret; | 130 | return ret; |
130 | } | 131 | } |
131 | 132 | ||
133 | iio_device_attach_buffer(indio_dev, buffer); | ||
134 | |||
132 | indio_dev->setup_ops = &ade7758_ring_setup_ops; | 135 | indio_dev->setup_ops = &ade7758_ring_setup_ops; |
133 | 136 | ||
134 | indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, | 137 | indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, |
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 | */ |
71 | struct iio_buffer { | 77 | struct 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); | |||
204 | bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, | 211 | bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, |
205 | const unsigned long *mask); | 212 | const unsigned long *mask); |
206 | 213 | ||
214 | struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer); | ||
215 | void 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 | */ | ||
226 | static 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 | ||
209 | static inline int iio_buffer_register(struct iio_dev *indio_dev, | 234 | 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, | |||
216 | static inline void iio_buffer_unregister(struct iio_dev *indio_dev) | 241 | static inline void iio_buffer_unregister(struct iio_dev *indio_dev) |
217 | {} | 242 | {} |
218 | 243 | ||
244 | static inline void iio_buffer_get(struct iio_buffer *buffer) {} | ||
245 | static 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_ */ |