Lines Matching +full:hte +full:- +full:gpio

1 // SPDX-License-Identifier: GPL-2.0
14 #include <linux/gpio.h>
15 #include <linux/gpio/driver.h>
16 #include <linux/hte.h>
32 #include <uapi/linux/gpio.h>
35 #include "gpiolib-cdev.h"
38 * Array sizes must ensure 64-bit alignment and not create holes in the
45 * Check that uAPI structs are 64-bit aligned for 32/64-bit compatibility
56 /* Character device interface to GPIO.
58 * The GPIO character device, /dev/gpiochipN, provides userspace an
63 * GPIO line handle management
68 * struct linehandle_state - contains the state of a userspace handle
69 * @gdev: the GPIO device the handle pertains to
71 * @descs: the GPIO descriptors held by this handle
99 return -EINVAL; in linehandle_validate_flags()
107 return -EINVAL; in linehandle_validate_flags()
116 return -EINVAL; in linehandle_validate_flags()
122 return -EINVAL; in linehandle_validate_flags()
130 return -EINVAL; in linehandle_validate_flags()
138 return -EINVAL; in linehandle_validate_flags()
172 return -EFAULT; in linehandle_set_config()
181 return -EINVAL; in linehandle_set_config()
183 for (i = 0; i < lh->num_descs; i++) { in linehandle_set_config()
184 desc = lh->descs[i]; in linehandle_set_config()
185 linehandle_flags_to_desc_flags(lflags, &desc->flags); in linehandle_set_config()
207 struct linehandle_state *lh = file->private_data; in linehandle_ioctl()
214 guard(srcu)(&lh->gdev->srcu); in linehandle_ioctl()
216 if (!rcu_access_pointer(lh->gdev->chip)) in linehandle_ioctl()
217 return -ENODEV; in linehandle_ioctl()
223 lh->num_descs, lh->descs, in linehandle_ioctl()
229 for (i = 0; i < lh->num_descs; i++) in linehandle_ioctl()
233 return -EFAULT; in linehandle_ioctl()
241 if (!test_bit(FLAG_IS_OUT, &lh->descs[0]->flags)) in linehandle_ioctl()
242 return -EPERM; in linehandle_ioctl()
245 return -EFAULT; in linehandle_ioctl()
248 for (i = 0; i < lh->num_descs; i++) in linehandle_ioctl()
254 lh->num_descs, in linehandle_ioctl()
255 lh->descs, in linehandle_ioctl()
261 return -EINVAL; in linehandle_ioctl()
277 for (i = 0; i < lh->num_descs; i++) in linehandle_free()
278 if (lh->descs[i]) in linehandle_free()
279 gpiod_free(lh->descs[i]); in linehandle_free()
280 kfree(lh->label); in linehandle_free()
281 gpio_device_put(lh->gdev); in linehandle_free()
287 linehandle_free(file->private_data); in linehandle_release()
310 return -EFAULT; in linehandle_create()
312 return -EINVAL; in linehandle_create()
322 return -ENOMEM; in linehandle_create()
323 lh->gdev = gpio_device_get(gdev); in linehandle_create()
327 lh->label = kstrndup(handlereq.consumer_label, in linehandle_create()
328 sizeof(handlereq.consumer_label) - 1, in linehandle_create()
330 if (!lh->label) { in linehandle_create()
331 ret = -ENOMEM; in linehandle_create()
336 lh->num_descs = handlereq.lines; in linehandle_create()
338 /* Request each GPIO */ in linehandle_create()
348 ret = gpiod_request_user(desc, lh->label); in linehandle_create()
351 lh->descs[i] = desc; in linehandle_create()
352 linehandle_flags_to_desc_flags(handlereq.flags, &desc->flags); in linehandle_create()
376 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linehandle_create()
386 file = anon_inode_getfile("gpio-linehandle", in linehandle_create()
403 return -EFAULT; in linehandle_create()
408 dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", in linehandle_create()
409 lh->num_descs); in linehandle_create()
422 * struct line - contains the state of a requested line
423 * @desc: the GPIO descriptor for this line.
425 * @irq: the interrupt triggered in response to events on this GPIO
437 * @hdesc: the Hardware Timestamp Engine (HTE) descriptor
445 * -- edge detector specific fields --
473 * -- debouncer specific fields --
491 * HTE provider sets line level at the time of event. The valid
496 * when sw_debounce is set on HTE enabled line, this is running
501 * when sw_debounce is set on HTE enabled line, this variable records
509 * struct linereq - contains the state of a userspace line request
510 * @gdev: the GPIO device the line request pertains to
511 * @label: consumer label used to tag GPIO descriptors
516 * @events: KFIFO for the GPIO events
521 * of configuration, particularly multi-step accesses to desc flags.
577 wake_up_poll(&lr->wait, EPOLLIN | EPOLLERR); in linereq_unregistered_notify()
587 scoped_guard(spinlock, &lr->wait.lock) { in linereq_put_event()
588 if (kfifo_is_full(&lr->events)) { in linereq_put_event()
590 kfifo_skip(&lr->events); in linereq_put_event()
592 kfifo_in(&lr->events, le, 1); in linereq_put_event()
595 wake_up_poll(&lr->wait, EPOLLIN); in linereq_put_event()
597 pr_debug_ratelimited("event FIFO is full - event dropped\n"); in linereq_put_event()
602 if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &line->desc->flags)) in line_event_timestamp()
605 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags)) in line_event_timestamp()
606 return line->timestamp_ns; in line_event_timestamp()
626 return ERR_PTR(-ENOMEM); in make_irq_label()
650 lr = line->req; in process_hw_ts_thread()
654 le.timestamp_ns = line->timestamp_ns; in process_hw_ts_thread()
655 edflags = READ_ONCE(line->edflags); in process_hw_ts_thread()
659 level = (line->raw_level >= 0) ? in process_hw_ts_thread()
660 line->raw_level : in process_hw_ts_thread()
661 gpiod_get_raw_value_cansleep(line->desc); in process_hw_ts_thread()
677 le.line_seqno = line->line_seqno; in process_hw_ts_thread()
678 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in process_hw_ts_thread()
679 le.offset = gpio_chip_hwgpio(line->desc); in process_hw_ts_thread()
696 line->timestamp_ns = ts->tsc; in process_hw_ts()
697 line->raw_level = ts->raw_level; in process_hw_ts()
698 lr = line->req; in process_hw_ts()
700 if (READ_ONCE(line->sw_debounced)) { in process_hw_ts()
701 line->total_discard_seq++; in process_hw_ts()
702 line->last_seqno = ts->seq; in process_hw_ts()
703 mod_delayed_work(system_wq, &line->work, in process_hw_ts()
704 usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us))); in process_hw_ts()
706 if (unlikely(ts->seq < line->line_seqno)) in process_hw_ts()
709 diff_seqno = ts->seq - line->line_seqno; in process_hw_ts()
710 line->line_seqno = ts->seq; in process_hw_ts()
711 if (lr->num_lines != 1) in process_hw_ts()
712 line->req_seqno = atomic_add_return(diff_seqno, in process_hw_ts()
713 &lr->seqno); in process_hw_ts()
725 struct hte_ts_desc *hdesc = &line->hdesc; in hte_edge_setup()
728 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
732 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
736 line->total_discard_seq = 0; in hte_edge_setup()
738 hte_init_line_attr(hdesc, desc_to_gpio(line->desc), flags, NULL, in hte_edge_setup()
739 line->desc); in hte_edge_setup()
760 struct linereq *lr = line->req; in edge_irq_thread()
766 if (line->timestamp_ns) { in edge_irq_thread()
767 le.timestamp_ns = line->timestamp_ns; in edge_irq_thread()
775 if (lr->num_lines != 1) in edge_irq_thread()
776 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_thread()
778 line->timestamp_ns = 0; in edge_irq_thread()
780 switch (READ_ONCE(line->edflags) & GPIO_V2_LINE_EDGE_FLAGS) { in edge_irq_thread()
782 le.id = line_event_id(gpiod_get_value_cansleep(line->desc)); in edge_irq_thread()
793 line->line_seqno++; in edge_irq_thread()
794 le.line_seqno = line->line_seqno; in edge_irq_thread()
795 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in edge_irq_thread()
796 le.offset = gpio_chip_hwgpio(line->desc); in edge_irq_thread()
806 struct linereq *lr = line->req; in edge_irq_handler()
812 line->timestamp_ns = line_event_timestamp(line); in edge_irq_handler()
814 if (lr->num_lines != 1) in edge_irq_handler()
815 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_handler()
828 * minor race - debouncer may be stopped here, so edge_detector_stop() in debounced_value()
832 value = READ_ONCE(line->level); in debounced_value()
834 if (test_bit(FLAG_ACTIVE_LOW, &line->desc->flags)) in debounced_value()
844 mod_delayed_work(system_wq, &line->work, in debounce_irq_handler()
845 usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us))); in debounce_irq_handler()
855 u64 eflags, edflags = READ_ONCE(line->edflags); in debounce_work_func()
856 int level = -1; in debounce_work_func()
861 level = line->raw_level; in debounce_work_func()
864 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_work_func()
870 if (READ_ONCE(line->level) == level) in debounce_work_func()
873 WRITE_ONCE(line->level, level); in debounce_work_func()
875 /* -- edge detection -- */ in debounce_work_func()
880 /* switch from physical level to logical - if they differ */ in debounce_work_func()
892 lr = line->req; in debounce_work_func()
894 le.offset = gpio_chip_hwgpio(line->desc); in debounce_work_func()
898 line->total_discard_seq -= 1; in debounce_work_func()
899 diff_seqno = line->last_seqno - line->total_discard_seq - in debounce_work_func()
900 line->line_seqno; in debounce_work_func()
901 line->line_seqno = line->last_seqno - line->total_discard_seq; in debounce_work_func()
902 le.line_seqno = line->line_seqno; in debounce_work_func()
903 le.seqno = (lr->num_lines == 1) ? in debounce_work_func()
904 le.line_seqno : atomic_add_return(diff_seqno, &lr->seqno); in debounce_work_func()
908 line->line_seqno++; in debounce_work_func()
909 le.line_seqno = line->line_seqno; in debounce_work_func()
910 le.seqno = (lr->num_lines == 1) ? in debounce_work_func()
911 le.line_seqno : atomic_inc_return(&lr->seqno); in debounce_work_func()
929 ret = gpio_do_set_config(line->desc, in debounce_setup()
932 if (ret != -ENOTSUPP) in debounce_setup()
937 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_setup()
942 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags))) { in debounce_setup()
943 irq = gpiod_to_irq(line->desc); in debounce_setup()
945 return -ENXIO; in debounce_setup()
947 label = make_irq_label(line->req->label); in debounce_setup()
949 return -ENOMEM; in debounce_setup()
958 line->irq = irq; in debounce_setup()
965 WRITE_ONCE(line->level, level); in debounce_setup()
966 WRITE_ONCE(line->sw_debounced, 1); in debounce_setup()
977 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_debounced()
978 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) && in gpio_v2_line_config_debounced()
979 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_debounced()
991 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_debounce_period()
992 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) && in gpio_v2_line_config_debounce_period()
993 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_debounce_period()
994 return lc->attrs[i].attr.debounce_period_us; in gpio_v2_line_config_debounce_period()
1001 if (line->irq) { in edge_detector_stop()
1002 free_irq_label(free_irq(line->irq, line)); in edge_detector_stop()
1003 line->irq = 0; in edge_detector_stop()
1007 if (READ_ONCE(line->edflags) & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE) in edge_detector_stop()
1008 hte_ts_put(&line->hdesc); in edge_detector_stop()
1011 cancel_delayed_work_sync(&line->work); in edge_detector_stop()
1012 WRITE_ONCE(line->sw_debounced, 0); in edge_detector_stop()
1013 WRITE_ONCE(line->edflags, 0); in edge_detector_stop()
1014 if (line->desc) in edge_detector_stop()
1015 WRITE_ONCE(line->desc->debounce_period_us, 0); in edge_detector_stop()
1016 /* do not change line->level - see comment in debounced_value() */ in edge_detector_stop()
1021 if (kfifo_initialized(&req->events)) in edge_detector_fifo_init()
1024 return kfifo_alloc(&req->events, req->event_buffer_size, GFP_KERNEL); in edge_detector_fifo_init()
1039 ret = edge_detector_fifo_init(line->req); in edge_detector_setup()
1048 WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us); in edge_detector_setup()
1052 if (!eflags || READ_ONCE(line->sw_debounced)) in edge_detector_setup()
1059 irq = gpiod_to_irq(line->desc); in edge_detector_setup()
1061 return -ENXIO; in edge_detector_setup()
1064 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1067 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1071 label = make_irq_label(line->req->label); in edge_detector_setup()
1083 line->irq = irq; in edge_detector_setup()
1091 u64 active_edflags = READ_ONCE(line->edflags); in edge_detector_update()
1096 (READ_ONCE(line->desc->debounce_period_us) == debounce_period_us)) in edge_detector_update()
1100 if (debounce_period_us && READ_ONCE(line->sw_debounced)) { in edge_detector_update()
1101 WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us); in edge_detector_update()
1107 return edge_detector_fifo_init(line->req); in edge_detector_update()
1113 if ((line->irq && !READ_ONCE(line->sw_debounced)) || in edge_detector_update()
1115 (!debounce_period_us && READ_ONCE(line->sw_debounced))) in edge_detector_update()
1127 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_flags()
1128 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_FLAGS) && in gpio_v2_line_config_flags()
1129 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_flags()
1130 return lc->attrs[i].attr.flags; in gpio_v2_line_config_flags()
1132 return lc->flags; in gpio_v2_line_config_flags()
1141 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_output_value()
1142 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES) && in gpio_v2_line_config_output_value()
1143 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_output_value()
1144 return !!(lc->attrs[i].attr.values & mask); in gpio_v2_line_config_output_value()
1153 return -EINVAL; in gpio_v2_line_flags_validate()
1157 return -EOPNOTSUPP; in gpio_v2_line_flags_validate()
1165 return -EINVAL; in gpio_v2_line_flags_validate()
1171 return -EINVAL; in gpio_v2_line_flags_validate()
1176 return -EINVAL; in gpio_v2_line_flags_validate()
1185 return -EINVAL; in gpio_v2_line_flags_validate()
1190 return -EINVAL; in gpio_v2_line_flags_validate()
1195 return -EINVAL; in gpio_v2_line_flags_validate()
1203 return -EINVAL; in gpio_v2_line_flags_validate()
1215 if (lc->num_attrs > GPIO_V2_LINE_NUM_ATTRS_MAX) in gpio_v2_line_config_validate()
1216 return -EINVAL; in gpio_v2_line_config_validate()
1218 if (!mem_is_zero(lc->padding, sizeof(lc->padding))) in gpio_v2_line_config_validate()
1219 return -EINVAL; in gpio_v2_line_config_validate()
1230 return -EINVAL; in gpio_v2_line_config_validate()
1284 return -EFAULT; in linereq_get_values()
1294 for (num_get = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1298 descs = &lr->lines[i].desc; in linereq_get_values()
1303 return -EINVAL; in linereq_get_values()
1309 return -ENOMEM; in linereq_get_values()
1310 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1312 descs[didx] = lr->lines[i].desc; in linereq_get_values()
1326 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1329 if (lr->lines[i].sw_debounced) in linereq_get_values()
1330 val = debounced_value(&lr->lines[i]); in linereq_get_values()
1340 return -EFAULT; in linereq_get_values()
1354 return -EFAULT; in linereq_set_values()
1356 guard(mutex)(&lr->config_mutex); in linereq_set_values()
1362 * is optimized to minimize scanning the lv->mask, and to avoid in linereq_set_values()
1367 for (num_set = 0, i = 0; i < lr->num_lines; i++) { in linereq_set_values()
1370 if (!test_bit(FLAG_IS_OUT, &lr->lines[i].desc->flags)) in linereq_set_values()
1371 return -EPERM; in linereq_set_values()
1377 descs = &lr->lines[i].desc; in linereq_set_values()
1381 return -EINVAL; in linereq_set_values()
1387 return -ENOMEM; in linereq_set_values()
1388 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_set_values()
1390 descs[didx] = lr->lines[i].desc; in linereq_set_values()
1413 return -EFAULT; in linereq_set_config()
1415 ret = gpio_v2_line_config_validate(&lc, lr->num_lines); in linereq_set_config()
1419 guard(mutex)(&lr->config_mutex); in linereq_set_config()
1421 for (i = 0; i < lr->num_lines; i++) { in linereq_set_config()
1422 line = &lr->lines[i]; in linereq_set_config()
1423 desc = lr->lines[i].desc; in linereq_set_config()
1431 gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); in linereq_set_config()
1450 WRITE_ONCE(line->edflags, edflags); in linereq_set_config()
1460 struct linereq *lr = file->private_data; in linereq_ioctl()
1463 guard(srcu)(&lr->gdev->srcu); in linereq_ioctl()
1465 if (!rcu_access_pointer(lr->gdev->chip)) in linereq_ioctl()
1466 return -ENODEV; in linereq_ioctl()
1476 return -EINVAL; in linereq_ioctl()
1491 struct linereq *lr = file->private_data; in linereq_poll()
1494 guard(srcu)(&lr->gdev->srcu); in linereq_poll()
1496 if (!rcu_access_pointer(lr->gdev->chip)) in linereq_poll()
1499 poll_wait(file, &lr->wait, wait); in linereq_poll()
1501 if (!kfifo_is_empty_spinlocked_noirqsave(&lr->events, in linereq_poll()
1502 &lr->wait.lock)) in linereq_poll()
1511 struct linereq *lr = file->private_data; in linereq_read()
1516 guard(srcu)(&lr->gdev->srcu); in linereq_read()
1518 if (!rcu_access_pointer(lr->gdev->chip)) in linereq_read()
1519 return -ENODEV; in linereq_read()
1522 return -EINVAL; in linereq_read()
1525 scoped_guard(spinlock, &lr->wait.lock) { in linereq_read()
1526 if (kfifo_is_empty(&lr->events)) { in linereq_read()
1530 if (file->f_flags & O_NONBLOCK) in linereq_read()
1531 return -EAGAIN; in linereq_read()
1533 ret = wait_event_interruptible_locked(lr->wait, in linereq_read()
1534 !kfifo_is_empty(&lr->events)); in linereq_read()
1539 if (kfifo_out(&lr->events, &le, 1) != 1) { in linereq_read()
1541 * This should never happen - we hold the in linereq_read()
1545 WARN(1, "failed to read from non-empty kfifo"); in linereq_read()
1546 return -EIO; in linereq_read()
1551 return -EFAULT; in linereq_read()
1562 if (lr->device_unregistered_nb.notifier_call) in linereq_free()
1563 blocking_notifier_chain_unregister(&lr->gdev->device_notifier, in linereq_free()
1564 &lr->device_unregistered_nb); in linereq_free()
1566 for (i = 0; i < lr->num_lines; i++) { in linereq_free()
1567 if (lr->lines[i].desc) { in linereq_free()
1568 edge_detector_stop(&lr->lines[i]); in linereq_free()
1569 gpiod_free(lr->lines[i].desc); in linereq_free()
1572 kfifo_free(&lr->events); in linereq_free()
1573 kfree(lr->label); in linereq_free()
1574 gpio_device_put(lr->gdev); in linereq_free()
1580 struct linereq *lr = file->private_data; in linereq_release()
1589 struct linereq *lr = file->private_data; in linereq_show_fdinfo()
1590 struct device *dev = &lr->gdev->dev; in linereq_show_fdinfo()
1593 seq_printf(out, "gpio-chip:\t%s\n", dev_name(dev)); in linereq_show_fdinfo()
1595 for (i = 0; i < lr->num_lines; i++) in linereq_show_fdinfo()
1596 seq_printf(out, "gpio-line:\t%d\n", in linereq_show_fdinfo()
1597 gpio_chip_hwgpio(lr->lines[i].desc)); in linereq_show_fdinfo()
1627 return -EFAULT; in linereq_create()
1630 return -EINVAL; in linereq_create()
1633 return -EINVAL; in linereq_create()
1642 return -ENOMEM; in linereq_create()
1643 lr->num_lines = ulr.num_lines; in linereq_create()
1645 lr->gdev = gpio_device_get(gdev); in linereq_create()
1648 lr->lines[i].req = lr; in linereq_create()
1649 WRITE_ONCE(lr->lines[i].sw_debounced, 0); in linereq_create()
1650 INIT_DELAYED_WORK(&lr->lines[i].work, debounce_work_func); in linereq_create()
1655 lr->label = kstrndup(ulr.consumer, sizeof(ulr.consumer) - 1, in linereq_create()
1657 if (!lr->label) { in linereq_create()
1658 ret = -ENOMEM; in linereq_create()
1663 mutex_init(&lr->config_mutex); in linereq_create()
1664 init_waitqueue_head(&lr->wait); in linereq_create()
1665 INIT_KFIFO(lr->events); in linereq_create()
1666 lr->event_buffer_size = ulr.event_buffer_size; in linereq_create()
1667 if (lr->event_buffer_size == 0) in linereq_create()
1668 lr->event_buffer_size = ulr.num_lines * 16; in linereq_create()
1669 else if (lr->event_buffer_size > GPIO_V2_LINES_MAX * 16) in linereq_create()
1670 lr->event_buffer_size = GPIO_V2_LINES_MAX * 16; in linereq_create()
1672 atomic_set(&lr->seqno, 0); in linereq_create()
1674 /* Request each GPIO */ in linereq_create()
1684 ret = gpiod_request_user(desc, lr->label); in linereq_create()
1688 lr->lines[i].desc = desc; in linereq_create()
1690 gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); in linereq_create()
1712 ret = edge_detector_setup(&lr->lines[i], lc, i, in linereq_create()
1718 lr->lines[i].edflags = edflags; in linereq_create()
1722 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linereq_create()
1726 lr->device_unregistered_nb.notifier_call = linereq_unregistered_notify; in linereq_create()
1727 ret = blocking_notifier_chain_register(&gdev->device_notifier, in linereq_create()
1728 &lr->device_unregistered_nb); in linereq_create()
1738 file = anon_inode_getfile("gpio-line", &line_fileops, lr, in linereq_create()
1753 return -EFAULT; in linereq_create()
1758 dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", in linereq_create()
1759 lr->num_lines); in linereq_create()
1773 * GPIO line event management
1777 * struct lineevent_state - contains the state of a userspace event
1778 * @gdev: the GPIO device the event pertains to
1780 * @desc: the GPIO descriptor held by this event
1782 * @irq: the interrupt that trigger in response to events on this GPIO
1785 * @events: KFIFO for the GPIO events
1809 struct lineevent_state *le = file->private_data; in lineevent_poll()
1812 guard(srcu)(&le->gdev->srcu); in lineevent_poll()
1814 if (!rcu_access_pointer(le->gdev->chip)) in lineevent_poll()
1817 poll_wait(file, &le->wait, wait); in lineevent_poll()
1819 if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock)) in lineevent_poll()
1831 wake_up_poll(&le->wait, EPOLLIN | EPOLLERR); in lineevent_unregistered_notify()
1844 struct lineevent_state *le = file->private_data; in lineevent_read()
1850 guard(srcu)(&le->gdev->srcu); in lineevent_read()
1852 if (!rcu_access_pointer(le->gdev->chip)) in lineevent_read()
1853 return -ENODEV; in lineevent_read()
1869 return -EINVAL; in lineevent_read()
1872 scoped_guard(spinlock, &le->wait.lock) { in lineevent_read()
1873 if (kfifo_is_empty(&le->events)) { in lineevent_read()
1877 if (file->f_flags & O_NONBLOCK) in lineevent_read()
1878 return -EAGAIN; in lineevent_read()
1880 ret = wait_event_interruptible_locked(le->wait, in lineevent_read()
1881 !kfifo_is_empty(&le->events)); in lineevent_read()
1886 if (kfifo_out(&le->events, &ge, 1) != 1) { in lineevent_read()
1888 * This should never happen - we hold the in lineevent_read()
1892 WARN(1, "failed to read from non-empty kfifo"); in lineevent_read()
1893 return -EIO; in lineevent_read()
1898 return -EFAULT; in lineevent_read()
1907 if (le->device_unregistered_nb.notifier_call) in lineevent_free()
1908 blocking_notifier_chain_unregister(&le->gdev->device_notifier, in lineevent_free()
1909 &le->device_unregistered_nb); in lineevent_free()
1910 if (le->irq) in lineevent_free()
1911 free_irq_label(free_irq(le->irq, le)); in lineevent_free()
1912 if (le->desc) in lineevent_free()
1913 gpiod_free(le->desc); in lineevent_free()
1914 kfree(le->label); in lineevent_free()
1915 gpio_device_put(le->gdev); in lineevent_free()
1921 lineevent_free(file->private_data); in lineevent_release()
1928 struct lineevent_state *le = file->private_data; in lineevent_ioctl()
1932 guard(srcu)(&le->gdev->srcu); in lineevent_ioctl()
1934 if (!rcu_access_pointer(le->gdev->chip)) in lineevent_ioctl()
1935 return -ENODEV; in lineevent_ioctl()
1946 val = gpiod_get_value_cansleep(le->desc); in lineevent_ioctl()
1952 return -EFAULT; in lineevent_ioctl()
1956 return -EINVAL; in lineevent_ioctl()
1992 if (!le->timestamp) in lineevent_irq_thread()
1995 ge.timestamp = le->timestamp; in lineevent_irq_thread()
1997 if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE in lineevent_irq_thread()
1998 && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { in lineevent_irq_thread()
1999 int level = gpiod_get_value_cansleep(le->desc); in lineevent_irq_thread()
2002 /* Emit low-to-high event */ in lineevent_irq_thread()
2005 /* Emit high-to-low event */ in lineevent_irq_thread()
2007 } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) { in lineevent_irq_thread()
2008 /* Emit low-to-high event */ in lineevent_irq_thread()
2010 } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { in lineevent_irq_thread()
2011 /* Emit high-to-low event */ in lineevent_irq_thread()
2017 ret = kfifo_in_spinlocked_noirqsave(&le->events, &ge, in lineevent_irq_thread()
2018 1, &le->wait.lock); in lineevent_irq_thread()
2020 wake_up_poll(&le->wait, EPOLLIN); in lineevent_irq_thread()
2022 pr_debug_ratelimited("event FIFO is full - event dropped\n"); in lineevent_irq_thread()
2035 le->timestamp = ktime_get_ns(); in lineevent_irq_handler()
2055 return -EFAULT; in lineevent_create()
2068 return -EINVAL; in lineevent_create()
2074 return -EINVAL; in lineevent_create()
2082 return -EINVAL; in lineevent_create()
2086 return -ENOMEM; in lineevent_create()
2087 le->gdev = gpio_device_get(gdev); in lineevent_create()
2091 le->label = kstrndup(eventreq.consumer_label, in lineevent_create()
2092 sizeof(eventreq.consumer_label) - 1, in lineevent_create()
2094 if (!le->label) { in lineevent_create()
2095 ret = -ENOMEM; in lineevent_create()
2100 ret = gpiod_request_user(desc, le->label); in lineevent_create()
2103 le->desc = desc; in lineevent_create()
2104 le->eflags = eflags; in lineevent_create()
2106 linehandle_flags_to_desc_flags(lflags, &desc->flags); in lineevent_create()
2116 ret = -ENODEV; in lineevent_create()
2121 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? in lineevent_create()
2124 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? in lineevent_create()
2128 INIT_KFIFO(le->events); in lineevent_create()
2129 init_waitqueue_head(&le->wait); in lineevent_create()
2131 le->device_unregistered_nb.notifier_call = lineevent_unregistered_notify; in lineevent_create()
2132 ret = blocking_notifier_chain_register(&gdev->device_notifier, in lineevent_create()
2133 &le->device_unregistered_nb); in lineevent_create()
2137 label = make_irq_label(le->label); in lineevent_create()
2155 le->irq = irq; in lineevent_create()
2163 file = anon_inode_getfile("gpio-event", in lineevent_create()
2180 return -EFAULT; in lineevent_create()
2197 u64 flagsv2 = info_v2->flags; in gpio_v2_line_info_to_v1()
2199 memcpy(info_v1->name, info_v2->name, sizeof(info_v1->name)); in gpio_v2_line_info_to_v1()
2200 memcpy(info_v1->consumer, info_v2->consumer, sizeof(info_v1->consumer)); in gpio_v2_line_info_to_v1()
2201 info_v1->line_offset = info_v2->offset; in gpio_v2_line_info_to_v1()
2202 info_v1->flags = 0; in gpio_v2_line_info_to_v1()
2205 info_v1->flags |= GPIOLINE_FLAG_KERNEL; in gpio_v2_line_info_to_v1()
2208 info_v1->flags |= GPIOLINE_FLAG_IS_OUT; in gpio_v2_line_info_to_v1()
2211 info_v1->flags |= GPIOLINE_FLAG_ACTIVE_LOW; in gpio_v2_line_info_to_v1()
2214 info_v1->flags |= GPIOLINE_FLAG_OPEN_DRAIN; in gpio_v2_line_info_to_v1()
2216 info_v1->flags |= GPIOLINE_FLAG_OPEN_SOURCE; in gpio_v2_line_info_to_v1()
2219 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_UP; in gpio_v2_line_info_to_v1()
2221 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN; in gpio_v2_line_info_to_v1()
2223 info_v1->flags |= GPIOLINE_FLAG_BIAS_DISABLE; in gpio_v2_line_info_to_v1()
2231 gpio_v2_line_info_to_v1(&lic_v2->info, &lic_v1->info); in gpio_v2_line_info_changed_to_v1()
2232 lic_v1->timestamp = lic_v2->timestamp_ns; in gpio_v2_line_info_changed_to_v1()
2233 lic_v1->event_type = lic_v2->event_type; in gpio_v2_line_info_changed_to_v1()
2250 info->offset = gpio_chip_hwgpio(desc); in gpio_desc_to_lineinfo()
2252 if (desc->name) in gpio_desc_to_lineinfo()
2253 strscpy(info->name, desc->name, sizeof(info->name)); in gpio_desc_to_lineinfo()
2255 dflags = READ_ONCE(desc->flags); in gpio_desc_to_lineinfo()
2257 scoped_guard(srcu, &desc->gdev->desc_srcu) { in gpio_desc_to_lineinfo()
2260 strscpy(info->consumer, label, in gpio_desc_to_lineinfo()
2261 sizeof(info->consumer)); in gpio_desc_to_lineinfo()
2265 * Userspace only need know that the kernel is using this GPIO so it in gpio_desc_to_lineinfo()
2271 * read on the other side of the transition - but that can always in gpio_desc_to_lineinfo()
2280 !gpiochip_line_is_valid(guard.gc, info->offset)) { in gpio_desc_to_lineinfo()
2281 info->flags |= GPIO_V2_LINE_FLAG_USED; in gpio_desc_to_lineinfo()
2283 if (!pinctrl_gpio_can_use_line(guard.gc, info->offset)) in gpio_desc_to_lineinfo()
2284 info->flags |= GPIO_V2_LINE_FLAG_USED; in gpio_desc_to_lineinfo()
2288 info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; in gpio_desc_to_lineinfo()
2290 info->flags |= GPIO_V2_LINE_FLAG_INPUT; in gpio_desc_to_lineinfo()
2293 info->flags |= GPIO_V2_LINE_FLAG_ACTIVE_LOW; in gpio_desc_to_lineinfo()
2296 info->flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN; in gpio_desc_to_lineinfo()
2298 info->flags |= GPIO_V2_LINE_FLAG_OPEN_SOURCE; in gpio_desc_to_lineinfo()
2301 info->flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; in gpio_desc_to_lineinfo()
2303 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; in gpio_desc_to_lineinfo()
2305 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; in gpio_desc_to_lineinfo()
2308 info->flags |= GPIO_V2_LINE_FLAG_EDGE_RISING; in gpio_desc_to_lineinfo()
2310 info->flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; in gpio_desc_to_lineinfo()
2313 info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME; in gpio_desc_to_lineinfo()
2315 info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE; in gpio_desc_to_lineinfo()
2317 debounce_period_us = READ_ONCE(desc->debounce_period_us); in gpio_desc_to_lineinfo()
2319 info->attrs[info->num_attrs].id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; in gpio_desc_to_lineinfo()
2320 info->attrs[info->num_attrs].debounce_period_us = in gpio_desc_to_lineinfo()
2322 info->num_attrs++; in gpio_desc_to_lineinfo()
2341 struct gpio_device *gdev = cdev->gdev; in chipinfo_get()
2346 strscpy(chipinfo.name, dev_name(&gdev->dev), sizeof(chipinfo.name)); in chipinfo_get()
2347 strscpy(chipinfo.label, gdev->label, sizeof(chipinfo.label)); in chipinfo_get()
2348 chipinfo.lines = gdev->ngpio; in chipinfo_get()
2350 return -EFAULT; in chipinfo_get()
2361 int abiv = atomic_cmpxchg(&cdata->watch_abi_version, 0, version); in lineinfo_ensure_abi_version()
2377 return -EFAULT; in lineinfo_get_v1()
2380 desc = gpio_device_get_desc(cdev->gdev, lineinfo.line_offset); in lineinfo_get_v1()
2386 return -EPERM; in lineinfo_get_v1()
2388 if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) in lineinfo_get_v1()
2389 return -EBUSY; in lineinfo_get_v1()
2397 clear_bit(lineinfo.line_offset, cdev->watched_lines); in lineinfo_get_v1()
2398 return -EFAULT; in lineinfo_get_v1()
2412 return -EFAULT; in lineinfo_get()
2415 return -EINVAL; in lineinfo_get()
2417 desc = gpio_device_get_desc(cdev->gdev, lineinfo.offset); in lineinfo_get()
2424 return -EPERM; in lineinfo_get()
2426 if (test_and_set_bit(lineinfo.offset, cdev->watched_lines)) in lineinfo_get()
2427 return -EBUSY; in lineinfo_get()
2433 clear_bit(lineinfo.offset, cdev->watched_lines); in lineinfo_get()
2434 return -EFAULT; in lineinfo_get()
2445 return -EFAULT; in lineinfo_unwatch()
2447 if (offset >= cdev->gdev->ngpio) in lineinfo_unwatch()
2448 return -EINVAL; in lineinfo_unwatch()
2450 if (!test_and_clear_bit(offset, cdev->watched_lines)) in lineinfo_unwatch()
2451 return -EBUSY; in lineinfo_unwatch()
2457 * gpio_ioctl() - ioctl handler for the GPIO chardev
2461 struct gpio_chardev_data *cdev = file->private_data; in gpio_ioctl()
2462 struct gpio_device *gdev = cdev->gdev; in gpio_ioctl()
2465 guard(srcu)(&gdev->srcu); in gpio_ioctl()
2468 if (!rcu_access_pointer(gdev->chip)) in gpio_ioctl()
2469 return -ENODEV; in gpio_ioctl()
2494 return -EINVAL; in gpio_ioctl()
2520 if (!(ctx->chg.info.flags & GPIO_V2_LINE_FLAG_USED)) { in lineinfo_changed_func()
2525 * not 100% bullet-proof, it's good enough for most cases. in lineinfo_changed_func()
2527 scoped_guard(srcu, &ctx->gdev->srcu) { in lineinfo_changed_func()
2528 gc = srcu_dereference(ctx->gdev->chip, &ctx->gdev->srcu); in lineinfo_changed_func()
2530 !pinctrl_gpio_can_use_line(gc, ctx->chg.info.offset)) in lineinfo_changed_func()
2531 ctx->chg.info.flags |= GPIO_V2_LINE_FLAG_USED; in lineinfo_changed_func()
2535 ret = kfifo_in_spinlocked(&ctx->cdev->events, &ctx->chg, 1, in lineinfo_changed_func()
2536 &ctx->cdev->wait.lock); in lineinfo_changed_func()
2538 wake_up_poll(&ctx->cdev->wait, EPOLLIN); in lineinfo_changed_func()
2540 pr_debug_ratelimited("lineinfo event FIFO is full - event dropped\n"); in lineinfo_changed_func()
2542 gpio_device_put(ctx->gdev); in lineinfo_changed_func()
2543 fput(ctx->cdev->fp); in lineinfo_changed_func()
2555 if (!test_bit(gpio_chip_hwgpio(desc), cdev->watched_lines)) in lineinfo_changed_notify()
2575 ctx->chg.event_type = action; in lineinfo_changed_notify()
2576 ctx->chg.timestamp_ns = ktime_get_ns(); in lineinfo_changed_notify()
2577 gpio_desc_to_lineinfo(desc, &ctx->chg.info, true); in lineinfo_changed_notify()
2578 /* Keep the GPIO device alive until we emit the event. */ in lineinfo_changed_notify()
2579 ctx->gdev = gpio_device_get(desc->gdev); in lineinfo_changed_notify()
2580 ctx->cdev = cdev; in lineinfo_changed_notify()
2582 get_file(ctx->cdev->fp); in lineinfo_changed_notify()
2584 INIT_WORK(&ctx->work, lineinfo_changed_func); in lineinfo_changed_notify()
2585 queue_work(ctx->gdev->line_state_wq, &ctx->work); in lineinfo_changed_notify()
2597 wake_up_poll(&cdev->wait, EPOLLIN | EPOLLERR); in gpio_device_unregistered_notify()
2605 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_poll()
2608 guard(srcu)(&cdev->gdev->srcu); in lineinfo_watch_poll()
2610 if (!rcu_access_pointer(cdev->gdev->chip)) in lineinfo_watch_poll()
2613 poll_wait(file, &cdev->wait, pollt); in lineinfo_watch_poll()
2615 if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events, in lineinfo_watch_poll()
2616 &cdev->wait.lock)) in lineinfo_watch_poll()
2625 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_read()
2631 guard(srcu)(&cdev->gdev->srcu); in lineinfo_watch_read()
2633 if (!rcu_access_pointer(cdev->gdev->chip)) in lineinfo_watch_read()
2634 return -ENODEV; in lineinfo_watch_read()
2639 return -EINVAL; in lineinfo_watch_read()
2643 scoped_guard(spinlock, &cdev->wait.lock) { in lineinfo_watch_read()
2644 if (kfifo_is_empty(&cdev->events)) { in lineinfo_watch_read()
2648 if (file->f_flags & O_NONBLOCK) in lineinfo_watch_read()
2649 return -EAGAIN; in lineinfo_watch_read()
2651 ret = wait_event_interruptible_locked(cdev->wait, in lineinfo_watch_read()
2652 !kfifo_is_empty(&cdev->events)); in lineinfo_watch_read()
2658 if (atomic_read(&cdev->watch_abi_version) == 2) in lineinfo_watch_read()
2663 return -EINVAL; in lineinfo_watch_read()
2665 if (kfifo_out(&cdev->events, &event, 1) != 1) { in lineinfo_watch_read()
2667 * This should never happen - we hold the in lineinfo_watch_read()
2671 WARN(1, "failed to read from non-empty kfifo"); in lineinfo_watch_read()
2672 return -EIO; in lineinfo_watch_read()
2679 return -EFAULT; in lineinfo_watch_read()
2686 return -EFAULT; in lineinfo_watch_read()
2690 return -EFAULT; in lineinfo_watch_read()
2699 * gpio_chrdev_open() - open the chardev for ioctl operations
2708 struct gpio_device *gdev = container_of(inode->i_cdev, in gpio_chrdev_open()
2711 int ret = -ENOMEM; in gpio_chrdev_open()
2713 guard(srcu)(&gdev->srcu); in gpio_chrdev_open()
2716 if (!rcu_access_pointer(gdev->chip)) in gpio_chrdev_open()
2717 return -ENODEV; in gpio_chrdev_open()
2721 return -ENODEV; in gpio_chrdev_open()
2723 cdev->watched_lines = bitmap_zalloc(gdev->ngpio, GFP_KERNEL); in gpio_chrdev_open()
2724 if (!cdev->watched_lines) in gpio_chrdev_open()
2727 init_waitqueue_head(&cdev->wait); in gpio_chrdev_open()
2728 INIT_KFIFO(cdev->events); in gpio_chrdev_open()
2729 cdev->gdev = gpio_device_get(gdev); in gpio_chrdev_open()
2731 cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify; in gpio_chrdev_open()
2732 scoped_guard(write_lock_irqsave, &gdev->line_state_lock) in gpio_chrdev_open()
2733 ret = raw_notifier_chain_register(&gdev->line_state_notifier, in gpio_chrdev_open()
2734 &cdev->lineinfo_changed_nb); in gpio_chrdev_open()
2738 cdev->device_unregistered_nb.notifier_call = in gpio_chrdev_open()
2740 ret = blocking_notifier_chain_register(&gdev->device_notifier, in gpio_chrdev_open()
2741 &cdev->device_unregistered_nb); in gpio_chrdev_open()
2745 file->private_data = cdev; in gpio_chrdev_open()
2746 cdev->fp = file; in gpio_chrdev_open()
2755 blocking_notifier_chain_unregister(&gdev->device_notifier, in gpio_chrdev_open()
2756 &cdev->device_unregistered_nb); in gpio_chrdev_open()
2758 scoped_guard(write_lock_irqsave, &gdev->line_state_lock) in gpio_chrdev_open()
2759 raw_notifier_chain_unregister(&gdev->line_state_notifier, in gpio_chrdev_open()
2760 &cdev->lineinfo_changed_nb); in gpio_chrdev_open()
2763 bitmap_free(cdev->watched_lines); in gpio_chrdev_open()
2770 * gpio_chrdev_release() - close chardev after ioctl operations
2779 struct gpio_chardev_data *cdev = file->private_data; in gpio_chrdev_release()
2780 struct gpio_device *gdev = cdev->gdev; in gpio_chrdev_release()
2782 blocking_notifier_chain_unregister(&gdev->device_notifier, in gpio_chrdev_release()
2783 &cdev->device_unregistered_nb); in gpio_chrdev_release()
2784 scoped_guard(write_lock_irqsave, &gdev->line_state_lock) in gpio_chrdev_release()
2785 raw_notifier_chain_unregister(&gdev->line_state_notifier, in gpio_chrdev_release()
2786 &cdev->lineinfo_changed_nb); in gpio_chrdev_release()
2787 bitmap_free(cdev->watched_lines); in gpio_chrdev_release()
2811 cdev_init(&gdev->chrdev, &gpio_fileops); in gpiolib_cdev_register()
2812 gdev->chrdev.owner = THIS_MODULE; in gpiolib_cdev_register()
2813 gdev->dev.devt = MKDEV(MAJOR(devt), gdev->id); in gpiolib_cdev_register()
2815 gdev->line_state_wq = alloc_ordered_workqueue("%s", WQ_HIGHPRI, in gpiolib_cdev_register()
2816 dev_name(&gdev->dev)); in gpiolib_cdev_register()
2817 if (!gdev->line_state_wq) in gpiolib_cdev_register()
2818 return -ENOMEM; in gpiolib_cdev_register()
2820 ret = cdev_device_add(&gdev->chrdev, &gdev->dev); in gpiolib_cdev_register()
2824 guard(srcu)(&gdev->srcu); in gpiolib_cdev_register()
2825 gc = srcu_dereference(gdev->chip, &gdev->srcu); in gpiolib_cdev_register()
2827 return -ENODEV; in gpiolib_cdev_register()
2829 chip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id); in gpiolib_cdev_register()
2836 destroy_workqueue(gdev->line_state_wq); in gpiolib_cdev_unregister()
2837 cdev_device_del(&gdev->chrdev, &gdev->dev); in gpiolib_cdev_unregister()
2838 blocking_notifier_call_chain(&gdev->device_notifier, 0, NULL); in gpiolib_cdev_unregister()