Lines Matching +full:chg +full:- +full:gpios
1 // SPDX-License-Identifier: GPL-2.0
36 #include "gpiolib-cdev.h"
39 * Array sizes must ensure 64-bit alignment and not create holes in the
46 * Check that uAPI structs are 64-bit aligned for 32/64-bit compatibility
60 * interface to gpiolib GPIOs via ioctl()s.
69 * struct linehandle_state - contains the state of a userspace handle
100 return -EINVAL; in linehandle_validate_flags()
108 return -EINVAL; in linehandle_validate_flags()
117 return -EINVAL; in linehandle_validate_flags()
123 return -EINVAL; in linehandle_validate_flags()
131 return -EINVAL; in linehandle_validate_flags()
139 return -EINVAL; in linehandle_validate_flags()
169 return -EFAULT; in linehandle_set_config()
178 return -EINVAL; in linehandle_set_config()
180 for (i = 0; i < lh->num_descs; i++) { in linehandle_set_config()
181 desc = lh->descs[i]; in linehandle_set_config()
182 linehandle_flags_to_desc_flags(lflags, &desc->flags); in linehandle_set_config()
204 struct linehandle_state *lh = file->private_data; in linehandle_ioctl()
211 guard(srcu)(&lh->gdev->srcu); in linehandle_ioctl()
213 if (!rcu_access_pointer(lh->gdev->chip)) in linehandle_ioctl()
214 return -ENODEV; in linehandle_ioctl()
220 lh->num_descs, lh->descs, in linehandle_ioctl()
226 for (i = 0; i < lh->num_descs; i++) in linehandle_ioctl()
230 return -EFAULT; in linehandle_ioctl()
238 if (!test_bit(FLAG_IS_OUT, &lh->descs[0]->flags)) in linehandle_ioctl()
239 return -EPERM; in linehandle_ioctl()
242 return -EFAULT; in linehandle_ioctl()
245 for (i = 0; i < lh->num_descs; i++) in linehandle_ioctl()
251 lh->num_descs, in linehandle_ioctl()
252 lh->descs, in linehandle_ioctl()
258 return -EINVAL; in linehandle_ioctl()
274 for (i = 0; i < lh->num_descs; i++) in linehandle_free()
275 if (lh->descs[i]) in linehandle_free()
276 gpiod_free(lh->descs[i]); in linehandle_free()
277 kfree(lh->label); in linehandle_free()
278 gpio_device_put(lh->gdev); in linehandle_free()
284 linehandle_free(file->private_data); in linehandle_release()
307 return -EFAULT; in linehandle_create()
309 return -EINVAL; in linehandle_create()
319 return -ENOMEM; in linehandle_create()
320 lh->gdev = gpio_device_get(gdev); in linehandle_create()
324 lh->label = kstrndup(handlereq.consumer_label, in linehandle_create()
325 sizeof(handlereq.consumer_label) - 1, in linehandle_create()
327 if (!lh->label) { in linehandle_create()
328 ret = -ENOMEM; in linehandle_create()
333 lh->num_descs = handlereq.lines; in linehandle_create()
345 ret = gpiod_request_user(desc, lh->label); in linehandle_create()
348 lh->descs[i] = desc; in linehandle_create()
349 linehandle_flags_to_desc_flags(handlereq.flags, &desc->flags); in linehandle_create()
373 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linehandle_create()
383 file = anon_inode_getfile("gpio-linehandle", in linehandle_create()
400 return -EFAULT; in linehandle_create()
405 dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", in linehandle_create()
406 lh->num_descs); in linehandle_create()
419 * struct line - contains the state of a requested line
445 * -- edge detector specific fields --
473 * -- debouncer specific fields --
529 * struct linereq - contains the state of a userspace line request
541 * of configuration, particularly multi-step accesses to desc flags and
569 if (line->desc < entry->desc) { in supinfo_insert()
570 new = &((*new)->rb_left); in supinfo_insert()
571 } else if (line->desc > entry->desc) { in supinfo_insert()
572 new = &((*new)->rb_right); in supinfo_insert()
580 rb_link_node(&line->node, parent, new); in supinfo_insert()
581 rb_insert_color(&line->node, &supinfo_tree); in supinfo_insert()
588 rb_erase(&line->node, &supinfo_tree); in supinfo_erase()
598 if (desc < line->desc) in supinfo_find()
599 node = node->rb_left; in supinfo_find()
600 else if (desc > line->desc) in supinfo_find()
601 node = node->rb_right; in supinfo_find()
620 attr = &info->attrs[info->num_attrs]; in supinfo_to_lineinfo()
621 attr->id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; in supinfo_to_lineinfo()
622 attr->debounce_period_us = READ_ONCE(line->debounce_period_us); in supinfo_to_lineinfo()
623 info->num_attrs++; in supinfo_to_lineinfo()
628 return READ_ONCE(line->debounce_period_us); in line_has_supinfo()
642 WRITE_ONCE(line->debounce_period_us, debounce_period_us); in line_set_debounce_period()
695 wake_up_poll(&lr->wait, EPOLLIN | EPOLLERR); in linereq_unregistered_notify()
705 scoped_guard(spinlock, &lr->wait.lock) { in linereq_put_event()
706 if (kfifo_is_full(&lr->events)) { in linereq_put_event()
708 kfifo_skip(&lr->events); in linereq_put_event()
710 kfifo_in(&lr->events, le, 1); in linereq_put_event()
713 wake_up_poll(&lr->wait, EPOLLIN); in linereq_put_event()
715 pr_debug_ratelimited("event FIFO is full - event dropped\n"); in linereq_put_event()
720 if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &line->desc->flags)) in line_event_timestamp()
723 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags)) in line_event_timestamp()
724 return line->timestamp_ns; in line_event_timestamp()
744 return ERR_PTR(-ENOMEM); in make_irq_label()
768 lr = line->req; in process_hw_ts_thread()
772 le.timestamp_ns = line->timestamp_ns; in process_hw_ts_thread()
773 edflags = READ_ONCE(line->edflags); in process_hw_ts_thread()
777 level = (line->raw_level >= 0) ? in process_hw_ts_thread()
778 line->raw_level : in process_hw_ts_thread()
779 gpiod_get_raw_value_cansleep(line->desc); in process_hw_ts_thread()
795 le.line_seqno = line->line_seqno; in process_hw_ts_thread()
796 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in process_hw_ts_thread()
797 le.offset = gpio_chip_hwgpio(line->desc); in process_hw_ts_thread()
814 line->timestamp_ns = ts->tsc; in process_hw_ts()
815 line->raw_level = ts->raw_level; in process_hw_ts()
816 lr = line->req; in process_hw_ts()
818 if (READ_ONCE(line->sw_debounced)) { in process_hw_ts()
819 line->total_discard_seq++; in process_hw_ts()
820 line->last_seqno = ts->seq; in process_hw_ts()
821 mod_delayed_work(system_wq, &line->work, in process_hw_ts()
822 usecs_to_jiffies(READ_ONCE(line->debounce_period_us))); in process_hw_ts()
824 if (unlikely(ts->seq < line->line_seqno)) in process_hw_ts()
827 diff_seqno = ts->seq - line->line_seqno; in process_hw_ts()
828 line->line_seqno = ts->seq; in process_hw_ts()
829 if (lr->num_lines != 1) in process_hw_ts()
830 line->req_seqno = atomic_add_return(diff_seqno, in process_hw_ts()
831 &lr->seqno); in process_hw_ts()
843 struct hte_ts_desc *hdesc = &line->hdesc; in hte_edge_setup()
846 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
850 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
854 line->total_discard_seq = 0; in hte_edge_setup()
856 hte_init_line_attr(hdesc, desc_to_gpio(line->desc), flags, NULL, in hte_edge_setup()
857 line->desc); in hte_edge_setup()
878 struct linereq *lr = line->req; in edge_irq_thread()
884 if (line->timestamp_ns) { in edge_irq_thread()
885 le.timestamp_ns = line->timestamp_ns; in edge_irq_thread()
893 if (lr->num_lines != 1) in edge_irq_thread()
894 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_thread()
896 line->timestamp_ns = 0; in edge_irq_thread()
898 switch (READ_ONCE(line->edflags) & GPIO_V2_LINE_EDGE_FLAGS) { in edge_irq_thread()
900 le.id = line_event_id(gpiod_get_value_cansleep(line->desc)); in edge_irq_thread()
911 line->line_seqno++; in edge_irq_thread()
912 le.line_seqno = line->line_seqno; in edge_irq_thread()
913 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in edge_irq_thread()
914 le.offset = gpio_chip_hwgpio(line->desc); in edge_irq_thread()
924 struct linereq *lr = line->req; in edge_irq_handler()
930 line->timestamp_ns = line_event_timestamp(line); in edge_irq_handler()
932 if (lr->num_lines != 1) in edge_irq_handler()
933 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_handler()
946 * minor race - debouncer may be stopped here, so edge_detector_stop() in debounced_value()
950 value = READ_ONCE(line->level); in debounced_value()
952 if (test_bit(FLAG_ACTIVE_LOW, &line->desc->flags)) in debounced_value()
962 mod_delayed_work(system_wq, &line->work, in debounce_irq_handler()
963 usecs_to_jiffies(READ_ONCE(line->debounce_period_us))); in debounce_irq_handler()
973 u64 eflags, edflags = READ_ONCE(line->edflags); in debounce_work_func()
974 int level = -1; in debounce_work_func()
979 level = line->raw_level; in debounce_work_func()
982 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_work_func()
988 if (READ_ONCE(line->level) == level) in debounce_work_func()
991 WRITE_ONCE(line->level, level); in debounce_work_func()
993 /* -- edge detection -- */ in debounce_work_func()
998 /* switch from physical level to logical - if they differ */ in debounce_work_func()
1010 lr = line->req; in debounce_work_func()
1012 le.offset = gpio_chip_hwgpio(line->desc); in debounce_work_func()
1016 line->total_discard_seq -= 1; in debounce_work_func()
1017 diff_seqno = line->last_seqno - line->total_discard_seq - in debounce_work_func()
1018 line->line_seqno; in debounce_work_func()
1019 line->line_seqno = line->last_seqno - line->total_discard_seq; in debounce_work_func()
1020 le.line_seqno = line->line_seqno; in debounce_work_func()
1021 le.seqno = (lr->num_lines == 1) ? in debounce_work_func()
1022 le.line_seqno : atomic_add_return(diff_seqno, &lr->seqno); in debounce_work_func()
1026 line->line_seqno++; in debounce_work_func()
1027 le.line_seqno = line->line_seqno; in debounce_work_func()
1028 le.seqno = (lr->num_lines == 1) ? in debounce_work_func()
1029 le.line_seqno : atomic_inc_return(&lr->seqno); in debounce_work_func()
1044 ret = gpiod_set_debounce(line->desc, debounce_period_us); in debounce_setup()
1049 if (ret != -ENOTSUPP) in debounce_setup()
1054 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_setup()
1059 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags))) { in debounce_setup()
1060 irq = gpiod_to_irq(line->desc); in debounce_setup()
1062 return -ENXIO; in debounce_setup()
1064 label = make_irq_label(line->req->label); in debounce_setup()
1066 return -ENOMEM; in debounce_setup()
1075 line->irq = irq; in debounce_setup()
1082 WRITE_ONCE(line->level, level); in debounce_setup()
1083 WRITE_ONCE(line->sw_debounced, 1); in debounce_setup()
1094 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_debounced()
1095 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) && in gpio_v2_line_config_debounced()
1096 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_debounced()
1108 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_debounce_period()
1109 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) && in gpio_v2_line_config_debounce_period()
1110 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_debounce_period()
1111 return lc->attrs[i].attr.debounce_period_us; in gpio_v2_line_config_debounce_period()
1118 if (line->irq) { in edge_detector_stop()
1119 free_irq_label(free_irq(line->irq, line)); in edge_detector_stop()
1120 line->irq = 0; in edge_detector_stop()
1124 if (READ_ONCE(line->edflags) & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE) in edge_detector_stop()
1125 hte_ts_put(&line->hdesc); in edge_detector_stop()
1128 cancel_delayed_work_sync(&line->work); in edge_detector_stop()
1129 WRITE_ONCE(line->sw_debounced, 0); in edge_detector_stop()
1130 WRITE_ONCE(line->edflags, 0); in edge_detector_stop()
1132 /* do not change line->level - see comment in debounced_value() */ in edge_detector_stop()
1137 if (kfifo_initialized(&req->events)) in edge_detector_fifo_init()
1140 return kfifo_alloc(&req->events, req->event_buffer_size, GFP_KERNEL); in edge_detector_fifo_init()
1155 ret = edge_detector_fifo_init(line->req); in edge_detector_setup()
1168 if (!eflags || READ_ONCE(line->sw_debounced)) in edge_detector_setup()
1175 irq = gpiod_to_irq(line->desc); in edge_detector_setup()
1177 return -ENXIO; in edge_detector_setup()
1180 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1183 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1187 label = make_irq_label(line->req->label); in edge_detector_setup()
1199 line->irq = irq; in edge_detector_setup()
1207 u64 active_edflags = READ_ONCE(line->edflags); in edge_detector_update()
1212 (READ_ONCE(line->debounce_period_us) == debounce_period_us)) in edge_detector_update()
1216 if (debounce_period_us && READ_ONCE(line->sw_debounced)) { in edge_detector_update()
1223 return edge_detector_fifo_init(line->req); in edge_detector_update()
1229 if ((line->irq && !READ_ONCE(line->sw_debounced)) || in edge_detector_update()
1231 (!debounce_period_us && READ_ONCE(line->sw_debounced))) in edge_detector_update()
1243 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_flags()
1244 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_FLAGS) && in gpio_v2_line_config_flags()
1245 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_flags()
1246 return lc->attrs[i].attr.flags; in gpio_v2_line_config_flags()
1248 return lc->flags; in gpio_v2_line_config_flags()
1257 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_output_value()
1258 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES) && in gpio_v2_line_config_output_value()
1259 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_output_value()
1260 return !!(lc->attrs[i].attr.values & mask); in gpio_v2_line_config_output_value()
1269 return -EINVAL; in gpio_v2_line_flags_validate()
1273 return -EOPNOTSUPP; in gpio_v2_line_flags_validate()
1281 return -EINVAL; in gpio_v2_line_flags_validate()
1287 return -EINVAL; in gpio_v2_line_flags_validate()
1292 return -EINVAL; in gpio_v2_line_flags_validate()
1301 return -EINVAL; in gpio_v2_line_flags_validate()
1306 return -EINVAL; in gpio_v2_line_flags_validate()
1311 return -EINVAL; in gpio_v2_line_flags_validate()
1319 return -EINVAL; in gpio_v2_line_flags_validate()
1331 if (lc->num_attrs > GPIO_V2_LINE_NUM_ATTRS_MAX) in gpio_v2_line_config_validate()
1332 return -EINVAL; in gpio_v2_line_config_validate()
1334 if (memchr_inv(lc->padding, 0, sizeof(lc->padding))) in gpio_v2_line_config_validate()
1335 return -EINVAL; in gpio_v2_line_config_validate()
1346 return -EINVAL; in gpio_v2_line_config_validate()
1396 return -EFAULT; in linereq_get_values()
1406 for (num_get = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1410 descs = &lr->lines[i].desc; in linereq_get_values()
1415 return -EINVAL; in linereq_get_values()
1421 return -ENOMEM; in linereq_get_values()
1422 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1424 descs[didx] = lr->lines[i].desc; in linereq_get_values()
1438 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1441 if (lr->lines[i].sw_debounced) in linereq_get_values()
1442 val = debounced_value(&lr->lines[i]); in linereq_get_values()
1452 return -EFAULT; in linereq_get_values()
1466 return -EFAULT; in linereq_set_values()
1468 guard(mutex)(&lr->config_mutex); in linereq_set_values()
1474 * is optimized to minimize scanning the lv->mask, and to avoid in linereq_set_values()
1479 for (num_set = 0, i = 0; i < lr->num_lines; i++) { in linereq_set_values()
1482 if (!test_bit(FLAG_IS_OUT, &lr->lines[i].desc->flags)) in linereq_set_values()
1483 return -EPERM; in linereq_set_values()
1489 descs = &lr->lines[i].desc; in linereq_set_values()
1493 return -EINVAL; in linereq_set_values()
1499 return -ENOMEM; in linereq_set_values()
1500 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_set_values()
1502 descs[didx] = lr->lines[i].desc; in linereq_set_values()
1525 return -EFAULT; in linereq_set_config()
1527 ret = gpio_v2_line_config_validate(&lc, lr->num_lines); in linereq_set_config()
1531 guard(mutex)(&lr->config_mutex); in linereq_set_config()
1533 for (i = 0; i < lr->num_lines; i++) { in linereq_set_config()
1534 line = &lr->lines[i]; in linereq_set_config()
1535 desc = lr->lines[i].desc; in linereq_set_config()
1543 gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); in linereq_set_config()
1562 WRITE_ONCE(line->edflags, edflags); in linereq_set_config()
1572 struct linereq *lr = file->private_data; in linereq_ioctl()
1575 guard(srcu)(&lr->gdev->srcu); in linereq_ioctl()
1577 if (!rcu_access_pointer(lr->gdev->chip)) in linereq_ioctl()
1578 return -ENODEV; in linereq_ioctl()
1588 return -EINVAL; in linereq_ioctl()
1603 struct linereq *lr = file->private_data; in linereq_poll()
1606 guard(srcu)(&lr->gdev->srcu); in linereq_poll()
1608 if (!rcu_access_pointer(lr->gdev->chip)) in linereq_poll()
1611 poll_wait(file, &lr->wait, wait); in linereq_poll()
1613 if (!kfifo_is_empty_spinlocked_noirqsave(&lr->events, in linereq_poll()
1614 &lr->wait.lock)) in linereq_poll()
1623 struct linereq *lr = file->private_data; in linereq_read()
1628 guard(srcu)(&lr->gdev->srcu); in linereq_read()
1630 if (!rcu_access_pointer(lr->gdev->chip)) in linereq_read()
1631 return -ENODEV; in linereq_read()
1634 return -EINVAL; in linereq_read()
1637 scoped_guard(spinlock, &lr->wait.lock) { in linereq_read()
1638 if (kfifo_is_empty(&lr->events)) { in linereq_read()
1642 if (file->f_flags & O_NONBLOCK) in linereq_read()
1643 return -EAGAIN; in linereq_read()
1645 ret = wait_event_interruptible_locked(lr->wait, in linereq_read()
1646 !kfifo_is_empty(&lr->events)); in linereq_read()
1651 if (kfifo_out(&lr->events, &le, 1) != 1) { in linereq_read()
1653 * This should never happen - we hold the in linereq_read()
1657 WARN(1, "failed to read from non-empty kfifo"); in linereq_read()
1658 return -EIO; in linereq_read()
1663 return -EFAULT; in linereq_read()
1675 if (lr->device_unregistered_nb.notifier_call) in linereq_free()
1676 blocking_notifier_chain_unregister(&lr->gdev->device_notifier, in linereq_free()
1677 &lr->device_unregistered_nb); in linereq_free()
1679 for (i = 0; i < lr->num_lines; i++) { in linereq_free()
1680 line = &lr->lines[i]; in linereq_free()
1681 if (!line->desc) in linereq_free()
1687 gpiod_free(line->desc); in linereq_free()
1689 kfifo_free(&lr->events); in linereq_free()
1690 kfree(lr->label); in linereq_free()
1691 gpio_device_put(lr->gdev); in linereq_free()
1697 struct linereq *lr = file->private_data; in linereq_release()
1706 struct linereq *lr = file->private_data; in linereq_show_fdinfo()
1707 struct device *dev = &lr->gdev->dev; in linereq_show_fdinfo()
1710 seq_printf(out, "gpio-chip:\t%s\n", dev_name(dev)); in linereq_show_fdinfo()
1712 for (i = 0; i < lr->num_lines; i++) in linereq_show_fdinfo()
1713 seq_printf(out, "gpio-line:\t%d\n", in linereq_show_fdinfo()
1714 gpio_chip_hwgpio(lr->lines[i].desc)); in linereq_show_fdinfo()
1744 return -EFAULT; in linereq_create()
1747 return -EINVAL; in linereq_create()
1750 return -EINVAL; in linereq_create()
1759 return -ENOMEM; in linereq_create()
1760 lr->num_lines = ulr.num_lines; in linereq_create()
1762 lr->gdev = gpio_device_get(gdev); in linereq_create()
1765 lr->lines[i].req = lr; in linereq_create()
1766 WRITE_ONCE(lr->lines[i].sw_debounced, 0); in linereq_create()
1767 INIT_DELAYED_WORK(&lr->lines[i].work, debounce_work_func); in linereq_create()
1772 lr->label = kstrndup(ulr.consumer, sizeof(ulr.consumer) - 1, in linereq_create()
1774 if (!lr->label) { in linereq_create()
1775 ret = -ENOMEM; in linereq_create()
1780 mutex_init(&lr->config_mutex); in linereq_create()
1781 init_waitqueue_head(&lr->wait); in linereq_create()
1782 INIT_KFIFO(lr->events); in linereq_create()
1783 lr->event_buffer_size = ulr.event_buffer_size; in linereq_create()
1784 if (lr->event_buffer_size == 0) in linereq_create()
1785 lr->event_buffer_size = ulr.num_lines * 16; in linereq_create()
1786 else if (lr->event_buffer_size > GPIO_V2_LINES_MAX * 16) in linereq_create()
1787 lr->event_buffer_size = GPIO_V2_LINES_MAX * 16; in linereq_create()
1789 atomic_set(&lr->seqno, 0); in linereq_create()
1801 ret = gpiod_request_user(desc, lr->label); in linereq_create()
1805 lr->lines[i].desc = desc; in linereq_create()
1807 gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); in linereq_create()
1829 ret = edge_detector_setup(&lr->lines[i], lc, i, in linereq_create()
1835 lr->lines[i].edflags = edflags; in linereq_create()
1839 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linereq_create()
1843 lr->device_unregistered_nb.notifier_call = linereq_unregistered_notify; in linereq_create()
1844 ret = blocking_notifier_chain_register(&gdev->device_notifier, in linereq_create()
1845 &lr->device_unregistered_nb); in linereq_create()
1855 file = anon_inode_getfile("gpio-line", &line_fileops, lr, in linereq_create()
1870 return -EFAULT; in linereq_create()
1875 dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", in linereq_create()
1876 lr->num_lines); in linereq_create()
1894 * struct lineevent_state - contains the state of a userspace event
1926 struct lineevent_state *le = file->private_data; in lineevent_poll()
1929 guard(srcu)(&le->gdev->srcu); in lineevent_poll()
1931 if (!rcu_access_pointer(le->gdev->chip)) in lineevent_poll()
1934 poll_wait(file, &le->wait, wait); in lineevent_poll()
1936 if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock)) in lineevent_poll()
1948 wake_up_poll(&le->wait, EPOLLIN | EPOLLERR); in lineevent_unregistered_notify()
1961 struct lineevent_state *le = file->private_data; in lineevent_read()
1967 guard(srcu)(&le->gdev->srcu); in lineevent_read()
1969 if (!rcu_access_pointer(le->gdev->chip)) in lineevent_read()
1970 return -ENODEV; in lineevent_read()
1986 return -EINVAL; in lineevent_read()
1989 scoped_guard(spinlock, &le->wait.lock) { in lineevent_read()
1990 if (kfifo_is_empty(&le->events)) { in lineevent_read()
1994 if (file->f_flags & O_NONBLOCK) in lineevent_read()
1995 return -EAGAIN; in lineevent_read()
1997 ret = wait_event_interruptible_locked(le->wait, in lineevent_read()
1998 !kfifo_is_empty(&le->events)); in lineevent_read()
2003 if (kfifo_out(&le->events, &ge, 1) != 1) { in lineevent_read()
2005 * This should never happen - we hold the in lineevent_read()
2009 WARN(1, "failed to read from non-empty kfifo"); in lineevent_read()
2010 return -EIO; in lineevent_read()
2015 return -EFAULT; in lineevent_read()
2024 if (le->device_unregistered_nb.notifier_call) in lineevent_free()
2025 blocking_notifier_chain_unregister(&le->gdev->device_notifier, in lineevent_free()
2026 &le->device_unregistered_nb); in lineevent_free()
2027 if (le->irq) in lineevent_free()
2028 free_irq_label(free_irq(le->irq, le)); in lineevent_free()
2029 if (le->desc) in lineevent_free()
2030 gpiod_free(le->desc); in lineevent_free()
2031 kfree(le->label); in lineevent_free()
2032 gpio_device_put(le->gdev); in lineevent_free()
2038 lineevent_free(file->private_data); in lineevent_release()
2045 struct lineevent_state *le = file->private_data; in lineevent_ioctl()
2049 guard(srcu)(&le->gdev->srcu); in lineevent_ioctl()
2051 if (!rcu_access_pointer(le->gdev->chip)) in lineevent_ioctl()
2052 return -ENODEV; in lineevent_ioctl()
2063 val = gpiod_get_value_cansleep(le->desc); in lineevent_ioctl()
2069 return -EFAULT; in lineevent_ioctl()
2073 return -EINVAL; in lineevent_ioctl()
2109 if (!le->timestamp) in lineevent_irq_thread()
2112 ge.timestamp = le->timestamp; in lineevent_irq_thread()
2114 if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE in lineevent_irq_thread()
2115 && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { in lineevent_irq_thread()
2116 int level = gpiod_get_value_cansleep(le->desc); in lineevent_irq_thread()
2119 /* Emit low-to-high event */ in lineevent_irq_thread()
2122 /* Emit high-to-low event */ in lineevent_irq_thread()
2124 } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) { in lineevent_irq_thread()
2125 /* Emit low-to-high event */ in lineevent_irq_thread()
2127 } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { in lineevent_irq_thread()
2128 /* Emit high-to-low event */ in lineevent_irq_thread()
2134 ret = kfifo_in_spinlocked_noirqsave(&le->events, &ge, in lineevent_irq_thread()
2135 1, &le->wait.lock); in lineevent_irq_thread()
2137 wake_up_poll(&le->wait, EPOLLIN); in lineevent_irq_thread()
2139 pr_debug_ratelimited("event FIFO is full - event dropped\n"); in lineevent_irq_thread()
2152 le->timestamp = ktime_get_ns(); in lineevent_irq_handler()
2172 return -EFAULT; in lineevent_create()
2185 return -EINVAL; in lineevent_create()
2191 return -EINVAL; in lineevent_create()
2199 return -EINVAL; in lineevent_create()
2203 return -ENOMEM; in lineevent_create()
2204 le->gdev = gpio_device_get(gdev); in lineevent_create()
2208 le->label = kstrndup(eventreq.consumer_label, in lineevent_create()
2209 sizeof(eventreq.consumer_label) - 1, in lineevent_create()
2211 if (!le->label) { in lineevent_create()
2212 ret = -ENOMEM; in lineevent_create()
2217 ret = gpiod_request_user(desc, le->label); in lineevent_create()
2220 le->desc = desc; in lineevent_create()
2221 le->eflags = eflags; in lineevent_create()
2223 linehandle_flags_to_desc_flags(lflags, &desc->flags); in lineevent_create()
2233 ret = -ENODEV; in lineevent_create()
2238 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? in lineevent_create()
2241 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? in lineevent_create()
2245 INIT_KFIFO(le->events); in lineevent_create()
2246 init_waitqueue_head(&le->wait); in lineevent_create()
2248 le->device_unregistered_nb.notifier_call = lineevent_unregistered_notify; in lineevent_create()
2249 ret = blocking_notifier_chain_register(&gdev->device_notifier, in lineevent_create()
2250 &le->device_unregistered_nb); in lineevent_create()
2254 label = make_irq_label(le->label); in lineevent_create()
2272 le->irq = irq; in lineevent_create()
2280 file = anon_inode_getfile("gpio-event", in lineevent_create()
2297 return -EFAULT; in lineevent_create()
2314 u64 flagsv2 = info_v2->flags; in gpio_v2_line_info_to_v1()
2316 memcpy(info_v1->name, info_v2->name, sizeof(info_v1->name)); in gpio_v2_line_info_to_v1()
2317 memcpy(info_v1->consumer, info_v2->consumer, sizeof(info_v1->consumer)); in gpio_v2_line_info_to_v1()
2318 info_v1->line_offset = info_v2->offset; in gpio_v2_line_info_to_v1()
2319 info_v1->flags = 0; in gpio_v2_line_info_to_v1()
2322 info_v1->flags |= GPIOLINE_FLAG_KERNEL; in gpio_v2_line_info_to_v1()
2325 info_v1->flags |= GPIOLINE_FLAG_IS_OUT; in gpio_v2_line_info_to_v1()
2328 info_v1->flags |= GPIOLINE_FLAG_ACTIVE_LOW; in gpio_v2_line_info_to_v1()
2331 info_v1->flags |= GPIOLINE_FLAG_OPEN_DRAIN; in gpio_v2_line_info_to_v1()
2333 info_v1->flags |= GPIOLINE_FLAG_OPEN_SOURCE; in gpio_v2_line_info_to_v1()
2336 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_UP; in gpio_v2_line_info_to_v1()
2338 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN; in gpio_v2_line_info_to_v1()
2340 info_v1->flags |= GPIOLINE_FLAG_BIAS_DISABLE; in gpio_v2_line_info_to_v1()
2348 gpio_v2_line_info_to_v1(&lic_v2->info, &lic_v1->info); in gpio_v2_line_info_changed_to_v1()
2349 lic_v1->timestamp = lic_v2->timestamp_ns; in gpio_v2_line_info_changed_to_v1()
2350 lic_v1->event_type = lic_v2->event_type; in gpio_v2_line_info_changed_to_v1()
2366 info->offset = gpio_chip_hwgpio(desc); in gpio_desc_to_lineinfo()
2368 if (desc->name) in gpio_desc_to_lineinfo()
2369 strscpy(info->name, desc->name, sizeof(info->name)); in gpio_desc_to_lineinfo()
2371 dflags = READ_ONCE(desc->flags); in gpio_desc_to_lineinfo()
2373 scoped_guard(srcu, &desc->gdev->desc_srcu) { in gpio_desc_to_lineinfo()
2376 strscpy(info->consumer, label, in gpio_desc_to_lineinfo()
2377 sizeof(info->consumer)); in gpio_desc_to_lineinfo()
2387 * read on the other side of the transition - but that can always in gpio_desc_to_lineinfo()
2397 !gpiochip_line_is_valid(guard.gc, info->offset) || in gpio_desc_to_lineinfo()
2398 !pinctrl_gpio_can_use_line(guard.gc, info->offset)) in gpio_desc_to_lineinfo()
2399 info->flags |= GPIO_V2_LINE_FLAG_USED; in gpio_desc_to_lineinfo()
2402 info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; in gpio_desc_to_lineinfo()
2404 info->flags |= GPIO_V2_LINE_FLAG_INPUT; in gpio_desc_to_lineinfo()
2407 info->flags |= GPIO_V2_LINE_FLAG_ACTIVE_LOW; in gpio_desc_to_lineinfo()
2410 info->flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN; in gpio_desc_to_lineinfo()
2412 info->flags |= GPIO_V2_LINE_FLAG_OPEN_SOURCE; in gpio_desc_to_lineinfo()
2415 info->flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; in gpio_desc_to_lineinfo()
2417 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; in gpio_desc_to_lineinfo()
2419 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; in gpio_desc_to_lineinfo()
2422 info->flags |= GPIO_V2_LINE_FLAG_EDGE_RISING; in gpio_desc_to_lineinfo()
2424 info->flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; in gpio_desc_to_lineinfo()
2427 info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME; in gpio_desc_to_lineinfo()
2429 info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE; in gpio_desc_to_lineinfo()
2446 struct gpio_device *gdev = cdev->gdev; in chipinfo_get()
2451 strscpy(chipinfo.name, dev_name(&gdev->dev), sizeof(chipinfo.name)); in chipinfo_get()
2452 strscpy(chipinfo.label, gdev->label, sizeof(chipinfo.label)); in chipinfo_get()
2453 chipinfo.lines = gdev->ngpio; in chipinfo_get()
2455 return -EFAULT; in chipinfo_get()
2466 int abiv = atomic_cmpxchg(&cdata->watch_abi_version, 0, version); in lineinfo_ensure_abi_version()
2482 return -EFAULT; in lineinfo_get_v1()
2485 desc = gpio_device_get_desc(cdev->gdev, lineinfo.line_offset); in lineinfo_get_v1()
2491 return -EPERM; in lineinfo_get_v1()
2493 if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) in lineinfo_get_v1()
2494 return -EBUSY; in lineinfo_get_v1()
2502 clear_bit(lineinfo.line_offset, cdev->watched_lines); in lineinfo_get_v1()
2503 return -EFAULT; in lineinfo_get_v1()
2517 return -EFAULT; in lineinfo_get()
2520 return -EINVAL; in lineinfo_get()
2522 desc = gpio_device_get_desc(cdev->gdev, lineinfo.offset); in lineinfo_get()
2529 return -EPERM; in lineinfo_get()
2531 if (test_and_set_bit(lineinfo.offset, cdev->watched_lines)) in lineinfo_get()
2532 return -EBUSY; in lineinfo_get()
2539 clear_bit(lineinfo.offset, cdev->watched_lines); in lineinfo_get()
2540 return -EFAULT; in lineinfo_get()
2551 return -EFAULT; in lineinfo_unwatch()
2553 if (offset >= cdev->gdev->ngpio) in lineinfo_unwatch()
2554 return -EINVAL; in lineinfo_unwatch()
2556 if (!test_and_clear_bit(offset, cdev->watched_lines)) in lineinfo_unwatch()
2557 return -EBUSY; in lineinfo_unwatch()
2563 * gpio_ioctl() - ioctl handler for the GPIO chardev
2567 struct gpio_chardev_data *cdev = file->private_data; in gpio_ioctl()
2568 struct gpio_device *gdev = cdev->gdev; in gpio_ioctl()
2571 guard(srcu)(&gdev->srcu); in gpio_ioctl()
2574 if (!rcu_access_pointer(gdev->chip)) in gpio_ioctl()
2575 return -ENODEV; in gpio_ioctl()
2600 return -EINVAL; in gpio_ioctl()
2617 struct gpio_v2_line_info_changed chg; in lineinfo_changed_notify() local
2621 if (!test_bit(gpio_chip_hwgpio(desc), cdev->watched_lines)) in lineinfo_changed_notify()
2624 memset(&chg, 0, sizeof(chg)); in lineinfo_changed_notify()
2625 chg.event_type = action; in lineinfo_changed_notify()
2626 chg.timestamp_ns = ktime_get_ns(); in lineinfo_changed_notify()
2627 gpio_desc_to_lineinfo(desc, &chg.info); in lineinfo_changed_notify()
2628 supinfo_to_lineinfo(desc, &chg.info); in lineinfo_changed_notify()
2630 ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock); in lineinfo_changed_notify()
2632 wake_up_poll(&cdev->wait, EPOLLIN); in lineinfo_changed_notify()
2634 pr_debug_ratelimited("lineinfo event FIFO is full - event dropped\n"); in lineinfo_changed_notify()
2646 wake_up_poll(&cdev->wait, EPOLLIN | EPOLLERR); in gpio_device_unregistered_notify()
2654 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_poll()
2657 guard(srcu)(&cdev->gdev->srcu); in lineinfo_watch_poll()
2659 if (!rcu_access_pointer(cdev->gdev->chip)) in lineinfo_watch_poll()
2662 poll_wait(file, &cdev->wait, pollt); in lineinfo_watch_poll()
2664 if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events, in lineinfo_watch_poll()
2665 &cdev->wait.lock)) in lineinfo_watch_poll()
2674 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_read()
2680 guard(srcu)(&cdev->gdev->srcu); in lineinfo_watch_read()
2682 if (!rcu_access_pointer(cdev->gdev->chip)) in lineinfo_watch_read()
2683 return -ENODEV; in lineinfo_watch_read()
2688 return -EINVAL; in lineinfo_watch_read()
2692 scoped_guard(spinlock, &cdev->wait.lock) { in lineinfo_watch_read()
2693 if (kfifo_is_empty(&cdev->events)) { in lineinfo_watch_read()
2697 if (file->f_flags & O_NONBLOCK) in lineinfo_watch_read()
2698 return -EAGAIN; in lineinfo_watch_read()
2700 ret = wait_event_interruptible_locked(cdev->wait, in lineinfo_watch_read()
2701 !kfifo_is_empty(&cdev->events)); in lineinfo_watch_read()
2707 if (atomic_read(&cdev->watch_abi_version) == 2) in lineinfo_watch_read()
2712 return -EINVAL; in lineinfo_watch_read()
2714 if (kfifo_out(&cdev->events, &event, 1) != 1) { in lineinfo_watch_read()
2716 * This should never happen - we hold the in lineinfo_watch_read()
2720 WARN(1, "failed to read from non-empty kfifo"); in lineinfo_watch_read()
2721 return -EIO; in lineinfo_watch_read()
2728 return -EFAULT; in lineinfo_watch_read()
2735 return -EFAULT; in lineinfo_watch_read()
2739 return -EFAULT; in lineinfo_watch_read()
2748 * gpio_chrdev_open() - open the chardev for ioctl operations
2757 struct gpio_device *gdev = container_of(inode->i_cdev, in gpio_chrdev_open()
2760 int ret = -ENOMEM; in gpio_chrdev_open()
2762 guard(srcu)(&gdev->srcu); in gpio_chrdev_open()
2765 if (!rcu_access_pointer(gdev->chip)) in gpio_chrdev_open()
2766 return -ENODEV; in gpio_chrdev_open()
2770 return -ENODEV; in gpio_chrdev_open()
2772 cdev->watched_lines = bitmap_zalloc(gdev->ngpio, GFP_KERNEL); in gpio_chrdev_open()
2773 if (!cdev->watched_lines) in gpio_chrdev_open()
2776 init_waitqueue_head(&cdev->wait); in gpio_chrdev_open()
2777 INIT_KFIFO(cdev->events); in gpio_chrdev_open()
2778 cdev->gdev = gpio_device_get(gdev); in gpio_chrdev_open()
2780 cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify; in gpio_chrdev_open()
2781 ret = blocking_notifier_chain_register(&gdev->line_state_notifier, in gpio_chrdev_open()
2782 &cdev->lineinfo_changed_nb); in gpio_chrdev_open()
2786 cdev->device_unregistered_nb.notifier_call = in gpio_chrdev_open()
2788 ret = blocking_notifier_chain_register(&gdev->device_notifier, in gpio_chrdev_open()
2789 &cdev->device_unregistered_nb); in gpio_chrdev_open()
2793 file->private_data = cdev; in gpio_chrdev_open()
2802 blocking_notifier_chain_unregister(&gdev->device_notifier, in gpio_chrdev_open()
2803 &cdev->device_unregistered_nb); in gpio_chrdev_open()
2805 blocking_notifier_chain_unregister(&gdev->line_state_notifier, in gpio_chrdev_open()
2806 &cdev->lineinfo_changed_nb); in gpio_chrdev_open()
2809 bitmap_free(cdev->watched_lines); in gpio_chrdev_open()
2816 * gpio_chrdev_release() - close chardev after ioctl operations
2825 struct gpio_chardev_data *cdev = file->private_data; in gpio_chrdev_release()
2826 struct gpio_device *gdev = cdev->gdev; in gpio_chrdev_release()
2828 blocking_notifier_chain_unregister(&gdev->device_notifier, in gpio_chrdev_release()
2829 &cdev->device_unregistered_nb); in gpio_chrdev_release()
2830 blocking_notifier_chain_unregister(&gdev->line_state_notifier, in gpio_chrdev_release()
2831 &cdev->lineinfo_changed_nb); in gpio_chrdev_release()
2832 bitmap_free(cdev->watched_lines); in gpio_chrdev_release()
2856 cdev_init(&gdev->chrdev, &gpio_fileops); in gpiolib_cdev_register()
2857 gdev->chrdev.owner = THIS_MODULE; in gpiolib_cdev_register()
2858 gdev->dev.devt = MKDEV(MAJOR(devt), gdev->id); in gpiolib_cdev_register()
2860 ret = cdev_device_add(&gdev->chrdev, &gdev->dev); in gpiolib_cdev_register()
2864 guard(srcu)(&gdev->srcu); in gpiolib_cdev_register()
2865 gc = srcu_dereference(gdev->chip, &gdev->srcu); in gpiolib_cdev_register()
2867 return -ENODEV; in gpiolib_cdev_register()
2869 chip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id); in gpiolib_cdev_register()
2876 cdev_device_del(&gdev->chrdev, &gdev->dev); in gpiolib_cdev_unregister()
2877 blocking_notifier_call_chain(&gdev->device_notifier, 0, NULL); in gpiolib_cdev_unregister()