1 #include <linux/slab.h>
2 #include <linux/kernel.h>
3 #include <linux/module.h>
4 #include <linux/device.h>
5 #include <linux/workqueue.h>
6 #include <linux/kfifo.h>
7 #include <linux/mutex.h>
12 struct iio_buffer buffer
;
16 struct mutex use_lock
;
19 #define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer)
21 static inline int __iio_allocate_kfifo(struct iio_kfifo
*buf
,
22 int bytes_per_datum
, int length
)
24 if ((length
== 0) || (bytes_per_datum
== 0))
27 __iio_update_buffer(&buf
->buffer
, bytes_per_datum
, length
);
28 return kfifo_alloc(&buf
->kf
, bytes_per_datum
*length
, GFP_KERNEL
);
31 static int iio_request_update_kfifo(struct iio_buffer
*r
)
34 struct iio_kfifo
*buf
= iio_to_kfifo(r
);
36 mutex_lock(&buf
->use_lock
);
37 if (!buf
->update_needed
)
44 ret
= __iio_allocate_kfifo(buf
, buf
->buffer
.bytes_per_datum
,
47 mutex_unlock(&buf
->use_lock
);
51 static void iio_mark_kfifo_in_use(struct iio_buffer
*r
)
53 struct iio_kfifo
*buf
= iio_to_kfifo(r
);
54 mutex_lock(&buf
->use_lock
);
56 mutex_unlock(&buf
->use_lock
);
59 static void iio_unmark_kfifo_in_use(struct iio_buffer
*r
)
61 struct iio_kfifo
*buf
= iio_to_kfifo(r
);
62 mutex_lock(&buf
->use_lock
);
64 mutex_unlock(&buf
->use_lock
);
67 static int iio_get_length_kfifo(struct iio_buffer
*r
)
72 static inline void __iio_init_kfifo(struct iio_kfifo
*kf
)
74 mutex_init(&kf
->use_lock
);
77 static IIO_BUFFER_ENABLE_ATTR
;
78 static IIO_BUFFER_BYTES_PER_DATUM_ATTR
;
79 static IIO_BUFFER_LENGTH_ATTR
;
81 static struct attribute
*iio_kfifo_attributes
[] = {
82 &dev_attr_length
.attr
,
83 &dev_attr_bytes_per_datum
.attr
,
84 &dev_attr_enable
.attr
,
88 static struct attribute_group iio_kfifo_attribute_group
= {
89 .attrs
= iio_kfifo_attributes
,
93 struct iio_buffer
*iio_kfifo_allocate(struct iio_dev
*indio_dev
)
97 kf
= kzalloc(sizeof *kf
, GFP_KERNEL
);
100 kf
->update_needed
= true;
101 iio_buffer_init(&kf
->buffer
, indio_dev
);
102 kf
->buffer
.attrs
= &iio_kfifo_attribute_group
;
103 __iio_init_kfifo(kf
);
107 EXPORT_SYMBOL(iio_kfifo_allocate
);
109 static int iio_get_bytes_per_datum_kfifo(struct iio_buffer
*r
)
111 return r
->bytes_per_datum
;
114 static int iio_set_bytes_per_datum_kfifo(struct iio_buffer
*r
, size_t bpd
)
116 if (r
->bytes_per_datum
!= bpd
) {
117 r
->bytes_per_datum
= bpd
;
118 if (r
->access
->mark_param_change
)
119 r
->access
->mark_param_change(r
);
124 static int iio_mark_update_needed_kfifo(struct iio_buffer
*r
)
126 struct iio_kfifo
*kf
= iio_to_kfifo(r
);
127 kf
->update_needed
= true;
131 static int iio_set_length_kfifo(struct iio_buffer
*r
, int length
)
133 if (r
->length
!= length
) {
135 if (r
->access
->mark_param_change
)
136 r
->access
->mark_param_change(r
);
141 void iio_kfifo_free(struct iio_buffer
*r
)
143 kfree(iio_to_kfifo(r
));
145 EXPORT_SYMBOL(iio_kfifo_free
);
147 static int iio_store_to_kfifo(struct iio_buffer
*r
,
152 struct iio_kfifo
*kf
= iio_to_kfifo(r
);
153 u8
*datal
= kmalloc(r
->bytes_per_datum
, GFP_KERNEL
);
154 memcpy(datal
, data
, r
->bytes_per_datum
- sizeof(timestamp
));
155 memcpy(datal
+ r
->bytes_per_datum
- sizeof(timestamp
),
156 ×tamp
, sizeof(timestamp
));
157 ret
= kfifo_in(&kf
->kf
, data
, r
->bytes_per_datum
);
158 if (ret
!= r
->bytes_per_datum
) {
166 static int iio_read_first_n_kfifo(struct iio_buffer
*r
,
167 size_t n
, char __user
*buf
)
170 struct iio_kfifo
*kf
= iio_to_kfifo(r
);
172 ret
= kfifo_to_user(&kf
->kf
, buf
, r
->bytes_per_datum
*n
, &copied
);
177 const struct iio_buffer_access_funcs kfifo_access_funcs
= {
178 .mark_in_use
= &iio_mark_kfifo_in_use
,
179 .unmark_in_use
= &iio_unmark_kfifo_in_use
,
180 .store_to
= &iio_store_to_kfifo
,
181 .read_first_n
= &iio_read_first_n_kfifo
,
182 .mark_param_change
= &iio_mark_update_needed_kfifo
,
183 .request_update
= &iio_request_update_kfifo
,
184 .get_bytes_per_datum
= &iio_get_bytes_per_datum_kfifo
,
185 .set_bytes_per_datum
= &iio_set_bytes_per_datum_kfifo
,
186 .get_length
= &iio_get_length_kfifo
,
187 .set_length
= &iio_set_length_kfifo
,
189 EXPORT_SYMBOL(kfifo_access_funcs
);
191 MODULE_LICENSE("GPL");