staging:iio: remove ability to escalate events.
[deliverable/linux.git] / drivers / staging / iio / industrialio-ring.c
CommitLineData
7026ea4b
JC
1/* The industrial I/O core
2 *
3 * Copyright (c) 2008 Jonathan Cameron
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * Handling of ring allocation / resizing.
10 *
11 *
12 * Things to look at here.
13 * - Better memory allocation techniques?
14 * - Alternative access techniques?
15 */
16#include <linux/kernel.h>
17#include <linux/device.h>
7026ea4b 18#include <linux/fs.h>
7026ea4b 19#include <linux/cdev.h>
5a0e3ad6 20#include <linux/slab.h>
7026ea4b
JC
21
22#include "iio.h"
23#include "ring_generic.h"
24
7026ea4b
JC
25int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
26 int event_code,
27 s64 timestamp)
28{
29 return __iio_push_event(&ring_buf->ev_int,
939606d5
JC
30 event_code,
31 timestamp);
7026ea4b
JC
32}
33EXPORT_SYMBOL(iio_push_ring_event);
34
7026ea4b 35/**
c3e5d410 36 * iio_ring_open() - chrdev file open for ring buffer access
7026ea4b
JC
37 *
38 * This function relies on all ring buffer implementations having an
39 * iio_ring_buffer as their first element.
40 **/
0deebb4f 41static int iio_ring_open(struct inode *inode, struct file *filp)
7026ea4b
JC
42{
43 struct iio_handler *hand
44 = container_of(inode->i_cdev, struct iio_handler, chrdev);
45 struct iio_ring_buffer *rb = hand->private;
46
47 filp->private_data = hand->private;
48 if (rb->access.mark_in_use)
49 rb->access.mark_in_use(rb);
50
51 return 0;
52}
53
54/**
c3e5d410 55 * iio_ring_release() - chrdev file close ring buffer access
7026ea4b
JC
56 *
57 * This function relies on all ring buffer implementations having an
58 * iio_ring_buffer as their first element.
59 **/
0deebb4f 60static int iio_ring_release(struct inode *inode, struct file *filp)
7026ea4b
JC
61{
62 struct cdev *cd = inode->i_cdev;
63 struct iio_handler *hand = iio_cdev_to_handler(cd);
64 struct iio_ring_buffer *rb = hand->private;
65
66 clear_bit(IIO_BUSY_BIT_POS, &rb->access_handler.flags);
67 if (rb->access.unmark_in_use)
68 rb->access.unmark_in_use(rb);
69
70 return 0;
71}
72
73/**
b4281733 74 * iio_ring_read_first_n_outer() - chrdev read for ring buffer access
7026ea4b
JC
75 *
76 * This function relies on all ring buffer implementations having an
77 * iio_ring _bufer as their first element.
78 **/
b4281733
JC
79static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
80 size_t n, loff_t *f_ps)
7026ea4b
JC
81{
82 struct iio_ring_buffer *rb = filp->private_data;
d5857d65
JC
83 int ret, dead_offset;
84
7026ea4b 85 /* rip lots must exist. */
b4281733 86 if (!rb->access.read_first_n)
7026ea4b 87 return -EINVAL;
b4281733 88 ret = rb->access.read_first_n(rb, n, buf, &dead_offset);
7026ea4b 89
7026ea4b
JC
90 return ret;
91}
92
93static const struct file_operations iio_ring_fileops = {
b4281733 94 .read = iio_ring_read_first_n_outer,
7026ea4b
JC
95 .release = iio_ring_release,
96 .open = iio_ring_open,
97 .owner = THIS_MODULE,
6038f373 98 .llseek = noop_llseek,
7026ea4b
JC
99};
100
101/**
c3e5d410 102 * __iio_request_ring_buffer_event_chrdev() - allocate ring event chrdev
7026ea4b 103 * @buf: ring buffer whose event chrdev we are allocating
c3e5d410 104 * @id: id of this ring buffer (typically 0)
7026ea4b
JC
105 * @owner: the module who owns the ring buffer (for ref counting)
106 * @dev: device with which the chrdev is associated
107 **/
108static inline int
109__iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf,
110 int id,
111 struct module *owner,
112 struct device *dev)
113{
114 int ret;
758d988c 115
ba5c6fba
JC
116 snprintf(buf->ev_int._name, sizeof(buf->ev_int._name),
117 "%s:event%d",
118 dev_name(&buf->dev),
3d550fba 119 id);
7026ea4b
JC
120 ret = iio_setup_ev_int(&(buf->ev_int),
121 buf->ev_int._name,
122 owner,
123 dev);
124 if (ret)
758d988c 125 goto error_ret;
7026ea4b
JC
126 return 0;
127
7026ea4b
JC
128error_ret:
129 return ret;
130}
131
132static inline void
133__iio_free_ring_buffer_event_chrdev(struct iio_ring_buffer *buf)
134{
135 iio_free_ev_int(&(buf->ev_int));
7026ea4b
JC
136}
137
138static void iio_ring_access_release(struct device *dev)
139{
140 struct iio_ring_buffer *buf
141 = access_dev_to_iio_ring_buffer(dev);
142 cdev_del(&buf->access_handler.chrdev);
143 iio_device_free_chrdev_minor(MINOR(dev->devt));
144}
145
146static struct device_type iio_ring_access_type = {
147 .release = iio_ring_access_release,
148};
149
150static inline int
151__iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf,
152 int id,
153 struct module *owner)
154{
155 int ret, minor;
156
157 buf->access_handler.flags = 0;
158
159 buf->access_dev.parent = &buf->dev;
5aaaeba8 160 buf->access_dev.bus = &iio_bus_type;
7026ea4b
JC
161 buf->access_dev.type = &iio_ring_access_type;
162 device_initialize(&buf->access_dev);
163
164 minor = iio_device_get_chrdev_minor();
165 if (minor < 0) {
166 ret = minor;
167 goto error_device_put;
168 }
169 buf->access_dev.devt = MKDEV(MAJOR(iio_devt), minor);
170
758d988c
JC
171
172 buf->access_id = id;
173
ba5c6fba
JC
174 dev_set_name(&buf->access_dev, "%s:access%d",
175 dev_name(&buf->dev),
176 buf->access_id);
7026ea4b
JC
177 ret = device_add(&buf->access_dev);
178 if (ret < 0) {
179 printk(KERN_ERR "failed to add the ring access dev\n");
758d988c 180 goto error_device_put;
7026ea4b
JC
181 }
182
183 cdev_init(&buf->access_handler.chrdev, &iio_ring_fileops);
184 buf->access_handler.chrdev.owner = owner;
185
186 ret = cdev_add(&buf->access_handler.chrdev, buf->access_dev.devt, 1);
187 if (ret) {
188 printk(KERN_ERR "failed to allocate ring access chrdev\n");
189 goto error_device_unregister;
190 }
191 return 0;
758d988c 192
7026ea4b
JC
193error_device_unregister:
194 device_unregister(&buf->access_dev);
7026ea4b
JC
195error_device_put:
196 put_device(&buf->access_dev);
197
198 return ret;
199}
200
201static void __iio_free_ring_buffer_access_chrdev(struct iio_ring_buffer *buf)
202{
7026ea4b
JC
203 device_unregister(&buf->access_dev);
204}
205
206void iio_ring_buffer_init(struct iio_ring_buffer *ring,
207 struct iio_dev *dev_info)
208{
209 if (ring->access.mark_param_change)
210 ring->access.mark_param_change(ring);
211 ring->indio_dev = dev_info;
212 ring->ev_int.private = ring;
213 ring->access_handler.private = ring;
214}
215EXPORT_SYMBOL(iio_ring_buffer_init);
216
1d892719
JC
217static ssize_t iio_show_scan_index(struct device *dev,
218 struct device_attribute *attr,
219 char *buf)
220{
221 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
222 return sprintf(buf, "%u\n", this_attr->c->scan_index);
223}
224
225static ssize_t iio_show_fixed_type(struct device *dev,
226 struct device_attribute *attr,
227 char *buf)
228{
229 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
230 return sprintf(buf, "%c%d/%d>>%u\n",
231 this_attr->c->scan_type.sign,
232 this_attr->c->scan_type.realbits,
233 this_attr->c->scan_type.storagebits,
234 this_attr->c->scan_type.shift);
235}
236
237static int __iio_add_chan_scan_elattr(const char *postfix,
238 const char *group,
239 const struct iio_chan_spec *chan,
240 struct device *dev,
241 struct list_head *attr_list)
7026ea4b
JC
242{
243 int ret;
1d892719
JC
244 struct iio_scan_el *scan_el;
245
246 scan_el = kzalloc(sizeof *scan_el, GFP_KERNEL);
247 if (scan_el == NULL) {
248 ret = -ENOMEM;
249 goto error_ret;
250 }
251 if (chan->type != IIO_TIMESTAMP)
252 ret = __iio_device_attr_init(&scan_el->dev_attr, postfix, chan,
253 iio_scan_el_show,
254 iio_scan_el_store, 0);
255 else /*
256 * Timestamp handled separately because it simplifies a lot of
257 * drivers by ensuring they don't have to know its magic index
258 */
259 ret = __iio_device_attr_init(&scan_el->dev_attr, postfix, chan,
260 iio_scan_el_ts_show,
261 iio_scan_el_ts_store, 0);
262 if (ret)
263 goto error_free_scan_el;
264
265 scan_el->number = chan->scan_index;
266
267 ret = sysfs_add_file_to_group(&dev->kobj,
268 &scan_el->dev_attr.attr,
269 group);
270 if (ret < 0)
271 goto error_device_attr_deinit;
272
273 list_add(&scan_el->l, attr_list);
274
275 return 0;
276error_device_attr_deinit:
277 __iio_device_attr_deinit(&scan_el->dev_attr);
278error_free_scan_el:
279 kfree(scan_el);
280error_ret:
281 return ret;
282}
283
284static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
285 const struct iio_chan_spec *chan)
286{
287 int ret;
288
289 ret = __iio_add_chan_devattr("index", "scan_elements",
290 chan,
291 &iio_show_scan_index,
292 NULL,
293 0,
294 0,
295 &ring->dev,
296 &ring->scan_el_dev_attr_list);
297 if (ret)
298 goto error_ret;
299
300 ret = __iio_add_chan_devattr("type", "scan_elements",
301 chan,
302 &iio_show_fixed_type,
303 NULL,
304 0,
305 0,
306 &ring->dev,
307 &ring->scan_el_dev_attr_list);
308
309 if (ret)
310 goto error_ret;
311
312 ret = __iio_add_chan_scan_elattr("en", "scan_elements",
313 chan, &ring->dev,
314 &ring->scan_el_en_attr_list);
315
316error_ret:
317 return ret;
318}
319
320static void iio_ring_remove_and_free_scan_el_attr(struct iio_ring_buffer *ring,
321 struct iio_scan_el *p)
322{
323 sysfs_remove_file_from_group(&ring->dev.kobj,
324 &p->dev_attr.attr, "scan_elements");
325 kfree(p->dev_attr.attr.name);
326 kfree(p);
327}
328
329static void iio_ring_remove_and_free_scan_dev_attr(struct iio_ring_buffer *ring,
330 struct iio_dev_attr *p)
331{
332 sysfs_remove_file_from_group(&ring->dev.kobj,
333 &p->dev_attr.attr, "scan_elements");
334 kfree(p->dev_attr.attr.name);
335 kfree(p);
336}
337
338static struct attribute *iio_scan_el_dummy_attrs[] = {
339 NULL
340};
341
342static struct attribute_group iio_scan_el_dummy_group = {
343 .name = "scan_elements",
344 .attrs = iio_scan_el_dummy_attrs
345};
346
347static void __iio_ring_attr_cleanup(struct iio_ring_buffer *ring)
348{
349 struct iio_dev_attr *p, *n;
350 struct iio_scan_el *q, *m;
351 int anydynamic = !(list_empty(&ring->scan_el_dev_attr_list) &&
352 list_empty(&ring->scan_el_en_attr_list));
353 list_for_each_entry_safe(p, n,
354 &ring->scan_el_dev_attr_list, l)
355 iio_ring_remove_and_free_scan_dev_attr(ring, p);
356 list_for_each_entry_safe(q, m,
357 &ring->scan_el_en_attr_list, l)
358 iio_ring_remove_and_free_scan_el_attr(ring, q);
359
360 if (ring->scan_el_attrs)
361 sysfs_remove_group(&ring->dev.kobj,
362 ring->scan_el_attrs);
363 else if (anydynamic)
364 sysfs_remove_group(&ring->dev.kobj,
365 &iio_scan_el_dummy_group);
366}
367
368int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
369 const struct iio_chan_spec *channels,
370 int num_channels)
371{
372 int ret, i;
758d988c
JC
373
374 ring->id = id;
7026ea4b 375
ba5c6fba
JC
376 dev_set_name(&ring->dev, "%s:buffer%d",
377 dev_name(ring->dev.parent),
378 ring->id);
7026ea4b
JC
379 ret = device_add(&ring->dev);
380 if (ret)
758d988c 381 goto error_ret;
7026ea4b
JC
382
383 ret = __iio_request_ring_buffer_event_chrdev(ring,
384 0,
385 ring->owner,
386 &ring->dev);
387 if (ret)
388 goto error_remove_device;
389
390 ret = __iio_request_ring_buffer_access_chrdev(ring,
391 0,
392 ring->owner);
393
394 if (ret)
395 goto error_free_ring_buffer_event_chrdev;
396
bf32963c
MS
397 if (ring->scan_el_attrs) {
398 ret = sysfs_create_group(&ring->dev.kobj,
399 ring->scan_el_attrs);
400 if (ret) {
401 dev_err(&ring->dev,
402 "Failed to add sysfs scan elements\n");
403 goto error_free_ring_buffer_event_chrdev;
404 }
1d892719
JC
405 } else if (channels) {
406 ret = sysfs_create_group(&ring->dev.kobj,
407 &iio_scan_el_dummy_group);
408 if (ret)
409 goto error_free_ring_buffer_event_chrdev;
bf32963c
MS
410 }
411
1d892719
JC
412
413 INIT_LIST_HEAD(&ring->scan_el_dev_attr_list);
414 INIT_LIST_HEAD(&ring->scan_el_en_attr_list);
415 if (channels) {
416 /* new magic */
417 for (i = 0; i < num_channels; i++) {
418 ret = iio_ring_add_channel_sysfs(ring, &channels[i]);
419 if (ret < 0)
420 goto error_cleanup_dynamic;
421 }
422 }
423
424 return 0;
425error_cleanup_dynamic:
426 __iio_ring_attr_cleanup(ring);
7026ea4b
JC
427error_free_ring_buffer_event_chrdev:
428 __iio_free_ring_buffer_event_chrdev(ring);
429error_remove_device:
430 device_del(&ring->dev);
7026ea4b
JC
431error_ret:
432 return ret;
433}
1d892719
JC
434EXPORT_SYMBOL(iio_ring_buffer_register_ex);
435
436int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
437{
438 return iio_ring_buffer_register_ex(ring, id, NULL, 0);
439}
7026ea4b
JC
440EXPORT_SYMBOL(iio_ring_buffer_register);
441
442void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
443{
1d892719 444 __iio_ring_attr_cleanup(ring);
7026ea4b
JC
445 __iio_free_ring_buffer_access_chrdev(ring);
446 __iio_free_ring_buffer_event_chrdev(ring);
447 device_del(&ring->dev);
7026ea4b
JC
448}
449EXPORT_SYMBOL(iio_ring_buffer_unregister);
450
451ssize_t iio_read_ring_length(struct device *dev,
452 struct device_attribute *attr,
453 char *buf)
454{
455 int len = 0;
456 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
457
458 if (ring->access.get_length)
459 len = sprintf(buf, "%d\n",
460 ring->access.get_length(ring));
461
462 return len;
463}
464EXPORT_SYMBOL(iio_read_ring_length);
465
0abd2428 466ssize_t iio_write_ring_length(struct device *dev,
7026ea4b
JC
467 struct device_attribute *attr,
468 const char *buf,
469 size_t len)
470{
471 int ret;
472 ulong val;
473 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
474 ret = strict_strtoul(buf, 10, &val);
475 if (ret)
476 return ret;
477
478 if (ring->access.get_length)
479 if (val == ring->access.get_length(ring))
480 return len;
481
482 if (ring->access.set_length) {
483 ring->access.set_length(ring, val);
484 if (ring->access.mark_param_change)
485 ring->access.mark_param_change(ring);
486 }
487
488 return len;
489}
490EXPORT_SYMBOL(iio_write_ring_length);
491
ffcab07a 492ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
7026ea4b
JC
493 struct device_attribute *attr,
494 char *buf)
495{
496 int len = 0;
497 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
498
ffcab07a 499 if (ring->access.get_bytes_per_datum)
7026ea4b 500 len = sprintf(buf, "%d\n",
ffcab07a 501 ring->access.get_bytes_per_datum(ring));
7026ea4b
JC
502
503 return len;
504}
ffcab07a 505EXPORT_SYMBOL(iio_read_ring_bytes_per_datum);
7026ea4b
JC
506
507ssize_t iio_store_ring_enable(struct device *dev,
508 struct device_attribute *attr,
509 const char *buf,
510 size_t len)
511{
512 int ret;
513 bool requested_state, current_state;
514 int previous_mode;
515 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
516 struct iio_dev *dev_info = ring->indio_dev;
517
518 mutex_lock(&dev_info->mlock);
519 previous_mode = dev_info->currentmode;
520 requested_state = !(buf[0] == '0');
521 current_state = !!(previous_mode & INDIO_ALL_RING_MODES);
522 if (current_state == requested_state) {
523 printk(KERN_INFO "iio-ring, current state requested again\n");
524 goto done;
525 }
526 if (requested_state) {
527 if (ring->preenable) {
528 ret = ring->preenable(dev_info);
529 if (ret) {
530 printk(KERN_ERR
531 "Buffer not started:"
532 "ring preenable failed\n");
533 goto error_ret;
534 }
535 }
536 if (ring->access.request_update) {
537 ret = ring->access.request_update(ring);
538 if (ret) {
539 printk(KERN_INFO
540 "Buffer not started:"
541 "ring parameter update failed\n");
542 goto error_ret;
543 }
544 }
545 if (ring->access.mark_in_use)
546 ring->access.mark_in_use(ring);
547 /* Definitely possible for devices to support both of these.*/
548 if (dev_info->modes & INDIO_RING_TRIGGERED) {
549 if (!dev_info->trig) {
550 printk(KERN_INFO
551 "Buffer not started: no trigger\n");
552 ret = -EINVAL;
553 if (ring->access.unmark_in_use)
554 ring->access.unmark_in_use(ring);
555 goto error_ret;
556 }
557 dev_info->currentmode = INDIO_RING_TRIGGERED;
558 } else if (dev_info->modes & INDIO_RING_HARDWARE_BUFFER)
559 dev_info->currentmode = INDIO_RING_HARDWARE_BUFFER;
560 else { /* should never be reached */
561 ret = -EINVAL;
562 goto error_ret;
563 }
564
565 if (ring->postenable) {
566
567 ret = ring->postenable(dev_info);
568 if (ret) {
569 printk(KERN_INFO
570 "Buffer not started:"
571 "postenable failed\n");
572 if (ring->access.unmark_in_use)
573 ring->access.unmark_in_use(ring);
574 dev_info->currentmode = previous_mode;
575 if (ring->postdisable)
576 ring->postdisable(dev_info);
577 goto error_ret;
578 }
579 }
580 } else {
581 if (ring->predisable) {
582 ret = ring->predisable(dev_info);
583 if (ret)
584 goto error_ret;
585 }
586 if (ring->access.unmark_in_use)
587 ring->access.unmark_in_use(ring);
588 dev_info->currentmode = INDIO_DIRECT_MODE;
589 if (ring->postdisable) {
590 ret = ring->postdisable(dev_info);
591 if (ret)
592 goto error_ret;
593 }
594 }
595done:
596 mutex_unlock(&dev_info->mlock);
597 return len;
598
599error_ret:
600 mutex_unlock(&dev_info->mlock);
601 return ret;
602}
603EXPORT_SYMBOL(iio_store_ring_enable);
604ssize_t iio_show_ring_enable(struct device *dev,
605 struct device_attribute *attr,
606 char *buf)
607{
608 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
609 return sprintf(buf, "%d\n", !!(ring->indio_dev->currentmode
610 & INDIO_ALL_RING_MODES));
611}
612EXPORT_SYMBOL(iio_show_ring_enable);
613
614ssize_t iio_scan_el_show(struct device *dev,
615 struct device_attribute *attr,
616 char *buf)
617{
618 int ret;
bf32963c 619 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
7026ea4b
JC
620 struct iio_scan_el *this_el = to_iio_scan_el(attr);
621
bf32963c 622 ret = iio_scan_mask_query(ring, this_el->number);
7026ea4b
JC
623 if (ret < 0)
624 return ret;
625 return sprintf(buf, "%d\n", ret);
626}
627EXPORT_SYMBOL(iio_scan_el_show);
628
629ssize_t iio_scan_el_store(struct device *dev,
630 struct device_attribute *attr,
631 const char *buf,
632 size_t len)
633{
634 int ret = 0;
635 bool state;
bf32963c
MS
636 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
637 struct iio_dev *indio_dev = ring->indio_dev;
7026ea4b
JC
638 struct iio_scan_el *this_el = to_iio_scan_el(attr);
639
640 state = !(buf[0] == '0');
641 mutex_lock(&indio_dev->mlock);
642 if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
643 ret = -EBUSY;
644 goto error_ret;
645 }
bf32963c 646 ret = iio_scan_mask_query(ring, this_el->number);
7026ea4b
JC
647 if (ret < 0)
648 goto error_ret;
649 if (!state && ret) {
bf32963c 650 ret = iio_scan_mask_clear(ring, this_el->number);
7026ea4b
JC
651 if (ret)
652 goto error_ret;
7026ea4b 653 } else if (state && !ret) {
bf32963c 654 ret = iio_scan_mask_set(ring, this_el->number);
7026ea4b
JC
655 if (ret)
656 goto error_ret;
7026ea4b
JC
657 }
658 if (this_el->set_state)
659 ret = this_el->set_state(this_el, indio_dev, state);
660error_ret:
661 mutex_unlock(&indio_dev->mlock);
662
663 return ret ? ret : len;
664
665}
666EXPORT_SYMBOL(iio_scan_el_store);
667
668ssize_t iio_scan_el_ts_show(struct device *dev,
669 struct device_attribute *attr,
670 char *buf)
671{
bf32963c
MS
672 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
673 return sprintf(buf, "%d\n", ring->scan_timestamp);
7026ea4b
JC
674}
675EXPORT_SYMBOL(iio_scan_el_ts_show);
676
677ssize_t iio_scan_el_ts_store(struct device *dev,
678 struct device_attribute *attr,
679 const char *buf,
680 size_t len)
681{
682 int ret = 0;
bf32963c
MS
683 struct iio_ring_buffer *ring = dev_get_drvdata(dev);
684 struct iio_dev *indio_dev = ring->indio_dev;
7026ea4b
JC
685 bool state;
686 state = !(buf[0] == '0');
687 mutex_lock(&indio_dev->mlock);
688 if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
689 ret = -EBUSY;
690 goto error_ret;
691 }
bf32963c 692 ring->scan_timestamp = state;
7026ea4b
JC
693error_ret:
694 mutex_unlock(&indio_dev->mlock);
695
696 return ret ? ret : len;
697}
698EXPORT_SYMBOL(iio_scan_el_ts_store);
This page took 0.245078 seconds and 5 git commands to generate.