Lines Matching +full:chg +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0
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
59 * interface to gpiolib GPIOs via ioctl()s.
73 down_read(&gdev->sem); in call_poll_locked()
75 up_read(&gdev->sem); in call_poll_locked()
86 down_read(&gdev->sem); in call_ioctl_locked()
88 up_read(&gdev->sem); in call_ioctl_locked()
99 down_read(&gdev->sem); in call_read_locked()
101 up_read(&gdev->sem); in call_read_locked()
112 * struct linehandle_state - contains the state of a userspace handle
143 return -EINVAL; in linehandle_validate_flags()
151 return -EINVAL; in linehandle_validate_flags()
160 return -EINVAL; in linehandle_validate_flags()
166 return -EINVAL; in linehandle_validate_flags()
174 return -EINVAL; in linehandle_validate_flags()
182 return -EINVAL; in linehandle_validate_flags()
212 return -EFAULT; in linehandle_set_config()
221 return -EINVAL; in linehandle_set_config()
223 for (i = 0; i < lh->num_descs; i++) { in linehandle_set_config()
224 desc = lh->descs[i]; in linehandle_set_config()
225 linehandle_flags_to_desc_flags(lflags, &desc->flags); in linehandle_set_config()
247 struct linehandle_state *lh = file->private_data; in linehandle_ioctl_unlocked()
254 if (!lh->gdev->chip) in linehandle_ioctl_unlocked()
255 return -ENODEV; in linehandle_ioctl_unlocked()
261 lh->num_descs, lh->descs, in linehandle_ioctl_unlocked()
267 for (i = 0; i < lh->num_descs; i++) in linehandle_ioctl_unlocked()
271 return -EFAULT; in linehandle_ioctl_unlocked()
279 if (!test_bit(FLAG_IS_OUT, &lh->descs[0]->flags)) in linehandle_ioctl_unlocked()
280 return -EPERM; in linehandle_ioctl_unlocked()
283 return -EFAULT; in linehandle_ioctl_unlocked()
286 for (i = 0; i < lh->num_descs; i++) in linehandle_ioctl_unlocked()
292 lh->num_descs, in linehandle_ioctl_unlocked()
293 lh->descs, in linehandle_ioctl_unlocked()
299 return -EINVAL; in linehandle_ioctl_unlocked()
306 struct linehandle_state *lh = file->private_data; in linehandle_ioctl()
308 return call_ioctl_locked(file, cmd, arg, lh->gdev, in linehandle_ioctl()
324 for (i = 0; i < lh->num_descs; i++) in linehandle_free()
325 if (lh->descs[i]) in linehandle_free()
326 gpiod_free(lh->descs[i]); in linehandle_free()
327 kfree(lh->label); in linehandle_free()
328 gpio_device_put(lh->gdev); in linehandle_free()
334 linehandle_free(file->private_data); in linehandle_release()
357 return -EFAULT; in linehandle_create()
359 return -EINVAL; in linehandle_create()
369 return -ENOMEM; in linehandle_create()
370 lh->gdev = gpio_device_get(gdev); in linehandle_create()
374 lh->label = kstrndup(handlereq.consumer_label, in linehandle_create()
375 sizeof(handlereq.consumer_label) - 1, in linehandle_create()
377 if (!lh->label) { in linehandle_create()
378 ret = -ENOMEM; in linehandle_create()
383 lh->num_descs = handlereq.lines; in linehandle_create()
388 struct gpio_desc *desc = gpiochip_get_desc(gdev->chip, offset); in linehandle_create()
395 ret = gpiod_request_user(desc, lh->label); in linehandle_create()
398 lh->descs[i] = desc; in linehandle_create()
399 linehandle_flags_to_desc_flags(handlereq.flags, &desc->flags); in linehandle_create()
423 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linehandle_create()
433 file = anon_inode_getfile("gpio-linehandle", in linehandle_create()
450 return -EFAULT; in linehandle_create()
455 dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", in linehandle_create()
456 lh->num_descs); in linehandle_create()
469 * struct line - contains the state of a requested line
495 * -- edge detector specific fields --
523 * -- debouncer specific fields --
579 * struct linereq - contains the state of a userspace line request
591 * of configuration, particularly multi-step accesses to desc flags and
619 if (line->desc < entry->desc) { in supinfo_insert()
620 new = &((*new)->rb_left); in supinfo_insert()
621 } else if (line->desc > entry->desc) { in supinfo_insert()
622 new = &((*new)->rb_right); in supinfo_insert()
630 rb_link_node(&line->node, parent, new); in supinfo_insert()
631 rb_insert_color(&line->node, &supinfo_tree); in supinfo_insert()
638 rb_erase(&line->node, &supinfo_tree); in supinfo_erase()
648 if (desc < line->desc) in supinfo_find()
649 node = node->rb_left; in supinfo_find()
650 else if (desc > line->desc) in supinfo_find()
651 node = node->rb_right; in supinfo_find()
670 attr = &info->attrs[info->num_attrs]; in supinfo_to_lineinfo()
671 attr->id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; in supinfo_to_lineinfo()
672 attr->debounce_period_us = READ_ONCE(line->debounce_period_us); in supinfo_to_lineinfo()
673 info->num_attrs++; in supinfo_to_lineinfo()
678 return READ_ONCE(line->debounce_period_us); in line_has_supinfo()
692 WRITE_ONCE(line->debounce_period_us, debounce_period_us); in line_set_debounce_period()
745 wake_up_poll(&lr->wait, EPOLLIN | EPOLLERR); in linereq_unregistered_notify()
755 spin_lock(&lr->wait.lock); in linereq_put_event()
756 if (kfifo_is_full(&lr->events)) { in linereq_put_event()
758 kfifo_skip(&lr->events); in linereq_put_event()
760 kfifo_in(&lr->events, le, 1); in linereq_put_event()
761 spin_unlock(&lr->wait.lock); in linereq_put_event()
763 wake_up_poll(&lr->wait, EPOLLIN); in linereq_put_event()
765 pr_debug_ratelimited("event FIFO is full - event dropped\n"); in linereq_put_event()
770 if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &line->desc->flags)) in line_event_timestamp()
773 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags)) in line_event_timestamp()
774 return line->timestamp_ns; in line_event_timestamp()
794 return ERR_PTR(-ENOMEM); in make_irq_label()
818 lr = line->req; in process_hw_ts_thread()
822 le.timestamp_ns = line->timestamp_ns; in process_hw_ts_thread()
823 edflags = READ_ONCE(line->edflags); in process_hw_ts_thread()
827 level = (line->raw_level >= 0) ? in process_hw_ts_thread()
828 line->raw_level : in process_hw_ts_thread()
829 gpiod_get_raw_value_cansleep(line->desc); in process_hw_ts_thread()
845 le.line_seqno = line->line_seqno; in process_hw_ts_thread()
846 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in process_hw_ts_thread()
847 le.offset = gpio_chip_hwgpio(line->desc); in process_hw_ts_thread()
864 line->timestamp_ns = ts->tsc; in process_hw_ts()
865 line->raw_level = ts->raw_level; in process_hw_ts()
866 lr = line->req; in process_hw_ts()
868 if (READ_ONCE(line->sw_debounced)) { in process_hw_ts()
869 line->total_discard_seq++; in process_hw_ts()
870 line->last_seqno = ts->seq; in process_hw_ts()
871 mod_delayed_work(system_wq, &line->work, in process_hw_ts()
872 usecs_to_jiffies(READ_ONCE(line->debounce_period_us))); in process_hw_ts()
874 if (unlikely(ts->seq < line->line_seqno)) in process_hw_ts()
877 diff_seqno = ts->seq - line->line_seqno; in process_hw_ts()
878 line->line_seqno = ts->seq; in process_hw_ts()
879 if (lr->num_lines != 1) in process_hw_ts()
880 line->req_seqno = atomic_add_return(diff_seqno, in process_hw_ts()
881 &lr->seqno); in process_hw_ts()
893 struct hte_ts_desc *hdesc = &line->hdesc; in hte_edge_setup()
896 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
900 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
904 line->total_discard_seq = 0; in hte_edge_setup()
906 hte_init_line_attr(hdesc, desc_to_gpio(line->desc), flags, NULL, in hte_edge_setup()
907 line->desc); in hte_edge_setup()
928 struct linereq *lr = line->req; in edge_irq_thread()
934 if (line->timestamp_ns) { in edge_irq_thread()
935 le.timestamp_ns = line->timestamp_ns; in edge_irq_thread()
943 if (lr->num_lines != 1) in edge_irq_thread()
944 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_thread()
946 line->timestamp_ns = 0; in edge_irq_thread()
948 switch (READ_ONCE(line->edflags) & GPIO_V2_LINE_EDGE_FLAGS) { in edge_irq_thread()
950 le.id = line_event_id(gpiod_get_value_cansleep(line->desc)); in edge_irq_thread()
961 line->line_seqno++; in edge_irq_thread()
962 le.line_seqno = line->line_seqno; in edge_irq_thread()
963 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in edge_irq_thread()
964 le.offset = gpio_chip_hwgpio(line->desc); in edge_irq_thread()
974 struct linereq *lr = line->req; in edge_irq_handler()
980 line->timestamp_ns = line_event_timestamp(line); in edge_irq_handler()
982 if (lr->num_lines != 1) in edge_irq_handler()
983 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_handler()
996 * minor race - debouncer may be stopped here, so edge_detector_stop() in debounced_value()
1000 value = READ_ONCE(line->level); in debounced_value()
1002 if (test_bit(FLAG_ACTIVE_LOW, &line->desc->flags)) in debounced_value()
1012 mod_delayed_work(system_wq, &line->work, in debounce_irq_handler()
1013 usecs_to_jiffies(READ_ONCE(line->debounce_period_us))); in debounce_irq_handler()
1023 u64 eflags, edflags = READ_ONCE(line->edflags); in debounce_work_func()
1024 int level = -1; in debounce_work_func()
1029 level = line->raw_level; in debounce_work_func()
1032 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_work_func()
1038 if (READ_ONCE(line->level) == level) in debounce_work_func()
1041 WRITE_ONCE(line->level, level); in debounce_work_func()
1043 /* -- edge detection -- */ in debounce_work_func()
1048 /* switch from physical level to logical - if they differ */ in debounce_work_func()
1060 lr = line->req; in debounce_work_func()
1062 le.offset = gpio_chip_hwgpio(line->desc); in debounce_work_func()
1066 line->total_discard_seq -= 1; in debounce_work_func()
1067 diff_seqno = line->last_seqno - line->total_discard_seq - in debounce_work_func()
1068 line->line_seqno; in debounce_work_func()
1069 line->line_seqno = line->last_seqno - line->total_discard_seq; in debounce_work_func()
1070 le.line_seqno = line->line_seqno; in debounce_work_func()
1071 le.seqno = (lr->num_lines == 1) ? in debounce_work_func()
1072 le.line_seqno : atomic_add_return(diff_seqno, &lr->seqno); in debounce_work_func()
1076 line->line_seqno++; in debounce_work_func()
1077 le.line_seqno = line->line_seqno; in debounce_work_func()
1078 le.seqno = (lr->num_lines == 1) ? in debounce_work_func()
1079 le.line_seqno : atomic_inc_return(&lr->seqno); in debounce_work_func()
1094 ret = gpiod_set_debounce(line->desc, debounce_period_us); in debounce_setup()
1099 if (ret != -ENOTSUPP) in debounce_setup()
1104 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_setup()
1109 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags))) { in debounce_setup()
1110 irq = gpiod_to_irq(line->desc); in debounce_setup()
1112 return -ENXIO; in debounce_setup()
1114 label = make_irq_label(line->req->label); in debounce_setup()
1116 return -ENOMEM; in debounce_setup()
1125 line->irq = irq; in debounce_setup()
1132 WRITE_ONCE(line->level, level); in debounce_setup()
1133 WRITE_ONCE(line->sw_debounced, 1); in debounce_setup()
1144 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_debounced()
1145 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) && in gpio_v2_line_config_debounced()
1146 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_debounced()
1158 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_debounce_period()
1159 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_DEBOUNCE) && in gpio_v2_line_config_debounce_period()
1160 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_debounce_period()
1161 return lc->attrs[i].attr.debounce_period_us; in gpio_v2_line_config_debounce_period()
1168 if (line->irq) { in edge_detector_stop()
1169 free_irq_label(free_irq(line->irq, line)); in edge_detector_stop()
1170 line->irq = 0; in edge_detector_stop()
1174 if (READ_ONCE(line->edflags) & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE) in edge_detector_stop()
1175 hte_ts_put(&line->hdesc); in edge_detector_stop()
1178 cancel_delayed_work_sync(&line->work); in edge_detector_stop()
1179 WRITE_ONCE(line->sw_debounced, 0); in edge_detector_stop()
1180 WRITE_ONCE(line->edflags, 0); in edge_detector_stop()
1182 /* do not change line->level - see comment in debounced_value() */ in edge_detector_stop()
1196 if (eflags && !kfifo_initialized(&line->req->events)) { in edge_detector_setup()
1197 ret = kfifo_alloc(&line->req->events, in edge_detector_setup()
1198 line->req->event_buffer_size, GFP_KERNEL); in edge_detector_setup()
1211 if (!eflags || READ_ONCE(line->sw_debounced)) in edge_detector_setup()
1218 irq = gpiod_to_irq(line->desc); in edge_detector_setup()
1220 return -ENXIO; in edge_detector_setup()
1223 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1226 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1230 label = make_irq_label(line->req->label); in edge_detector_setup()
1242 line->irq = irq; in edge_detector_setup()
1252 u64 active_edflags = READ_ONCE(line->edflags); in edge_detector_update()
1257 (READ_ONCE(line->debounce_period_us) == debounce_period_us)) in edge_detector_update()
1261 if (debounce_period_us && READ_ONCE(line->sw_debounced)) { in edge_detector_update()
1268 if (eflags && !kfifo_initialized(&line->req->events)) { in edge_detector_update()
1269 ret = kfifo_alloc(&line->req->events, in edge_detector_update()
1270 line->req->event_buffer_size, in edge_detector_update()
1279 if ((line->irq && !READ_ONCE(line->sw_debounced)) || in edge_detector_update()
1281 (!debounce_period_us && READ_ONCE(line->sw_debounced))) in edge_detector_update()
1293 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_flags()
1294 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_FLAGS) && in gpio_v2_line_config_flags()
1295 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_flags()
1296 return lc->attrs[i].attr.flags; in gpio_v2_line_config_flags()
1298 return lc->flags; in gpio_v2_line_config_flags()
1307 for (i = 0; i < lc->num_attrs; i++) { in gpio_v2_line_config_output_value()
1308 if ((lc->attrs[i].attr.id == GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES) && in gpio_v2_line_config_output_value()
1309 (lc->attrs[i].mask & mask)) in gpio_v2_line_config_output_value()
1310 return !!(lc->attrs[i].attr.values & mask); in gpio_v2_line_config_output_value()
1319 return -EINVAL; in gpio_v2_line_flags_validate()
1323 return -EOPNOTSUPP; in gpio_v2_line_flags_validate()
1331 return -EINVAL; in gpio_v2_line_flags_validate()
1337 return -EINVAL; in gpio_v2_line_flags_validate()
1342 return -EINVAL; in gpio_v2_line_flags_validate()
1351 return -EINVAL; in gpio_v2_line_flags_validate()
1356 return -EINVAL; in gpio_v2_line_flags_validate()
1361 return -EINVAL; in gpio_v2_line_flags_validate()
1369 return -EINVAL; in gpio_v2_line_flags_validate()
1381 if (lc->num_attrs > GPIO_V2_LINE_NUM_ATTRS_MAX) in gpio_v2_line_config_validate()
1382 return -EINVAL; in gpio_v2_line_config_validate()
1384 if (memchr_inv(lc->padding, 0, sizeof(lc->padding))) in gpio_v2_line_config_validate()
1385 return -EINVAL; in gpio_v2_line_config_validate()
1396 return -EINVAL; in gpio_v2_line_config_validate()
1446 return -EFAULT; in linereq_get_values()
1448 for (num_get = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1451 descs = &lr->lines[i].desc; in linereq_get_values()
1456 return -EINVAL; in linereq_get_values()
1461 return -ENOMEM; in linereq_get_values()
1462 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1464 descs[didx] = lr->lines[i].desc; in linereq_get_values()
1478 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_get_values()
1480 if (lr->lines[i].sw_debounced) in linereq_get_values()
1481 val = debounced_value(&lr->lines[i]); in linereq_get_values()
1491 return -EFAULT; in linereq_get_values()
1505 for (num_set = 0, i = 0; i < lr->num_lines; i++) { in linereq_set_values_unlocked()
1506 if (lv->mask & BIT_ULL(i)) { in linereq_set_values_unlocked()
1507 if (!test_bit(FLAG_IS_OUT, &lr->lines[i].desc->flags)) in linereq_set_values_unlocked()
1508 return -EPERM; in linereq_set_values_unlocked()
1509 if (lv->bits & BIT_ULL(i)) in linereq_set_values_unlocked()
1512 descs = &lr->lines[i].desc; in linereq_set_values_unlocked()
1516 return -EINVAL; in linereq_set_values_unlocked()
1522 return -ENOMEM; in linereq_set_values_unlocked()
1523 for (didx = 0, i = 0; i < lr->num_lines; i++) { in linereq_set_values_unlocked()
1524 if (lv->mask & BIT_ULL(i)) { in linereq_set_values_unlocked()
1525 descs[didx] = lr->lines[i].desc; in linereq_set_values_unlocked()
1544 return -EFAULT; in linereq_set_values()
1546 mutex_lock(&lr->config_mutex); in linereq_set_values()
1550 mutex_unlock(&lr->config_mutex); in linereq_set_values()
1564 for (i = 0; i < lr->num_lines; i++) { in linereq_set_config_unlocked()
1565 line = &lr->lines[i]; in linereq_set_config_unlocked()
1566 desc = lr->lines[i].desc; in linereq_set_config_unlocked()
1574 gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); in linereq_set_config_unlocked()
1593 WRITE_ONCE(line->edflags, edflags); in linereq_set_config_unlocked()
1606 return -EFAULT; in linereq_set_config()
1608 ret = gpio_v2_line_config_validate(&lc, lr->num_lines); in linereq_set_config()
1612 mutex_lock(&lr->config_mutex); in linereq_set_config()
1616 mutex_unlock(&lr->config_mutex); in linereq_set_config()
1624 struct linereq *lr = file->private_data; in linereq_ioctl_unlocked()
1627 if (!lr->gdev->chip) in linereq_ioctl_unlocked()
1628 return -ENODEV; in linereq_ioctl_unlocked()
1638 return -EINVAL; in linereq_ioctl_unlocked()
1645 struct linereq *lr = file->private_data; in linereq_ioctl()
1647 return call_ioctl_locked(file, cmd, arg, lr->gdev, in linereq_ioctl()
1662 struct linereq *lr = file->private_data; in linereq_poll_unlocked()
1665 if (!lr->gdev->chip) in linereq_poll_unlocked()
1668 poll_wait(file, &lr->wait, wait); in linereq_poll_unlocked()
1670 if (!kfifo_is_empty_spinlocked_noirqsave(&lr->events, in linereq_poll_unlocked()
1671 &lr->wait.lock)) in linereq_poll_unlocked()
1680 struct linereq *lr = file->private_data; in linereq_poll()
1682 return call_poll_locked(file, wait, lr->gdev, linereq_poll_unlocked); in linereq_poll()
1688 struct linereq *lr = file->private_data; in linereq_read_unlocked()
1693 if (!lr->gdev->chip) in linereq_read_unlocked()
1694 return -ENODEV; in linereq_read_unlocked()
1697 return -EINVAL; in linereq_read_unlocked()
1700 spin_lock(&lr->wait.lock); in linereq_read_unlocked()
1701 if (kfifo_is_empty(&lr->events)) { in linereq_read_unlocked()
1703 spin_unlock(&lr->wait.lock); in linereq_read_unlocked()
1707 if (file->f_flags & O_NONBLOCK) { in linereq_read_unlocked()
1708 spin_unlock(&lr->wait.lock); in linereq_read_unlocked()
1709 return -EAGAIN; in linereq_read_unlocked()
1712 ret = wait_event_interruptible_locked(lr->wait, in linereq_read_unlocked()
1713 !kfifo_is_empty(&lr->events)); in linereq_read_unlocked()
1715 spin_unlock(&lr->wait.lock); in linereq_read_unlocked()
1720 ret = kfifo_out(&lr->events, &le, 1); in linereq_read_unlocked()
1721 spin_unlock(&lr->wait.lock); in linereq_read_unlocked()
1724 * This should never happen - we were holding the in linereq_read_unlocked()
1728 ret = -EIO; in linereq_read_unlocked()
1733 return -EFAULT; in linereq_read_unlocked()
1743 struct linereq *lr = file->private_data; in linereq_read()
1745 return call_read_locked(file, buf, count, f_ps, lr->gdev, in linereq_read()
1754 if (lr->device_unregistered_nb.notifier_call) in linereq_free()
1755 blocking_notifier_chain_unregister(&lr->gdev->device_notifier, in linereq_free()
1756 &lr->device_unregistered_nb); in linereq_free()
1758 for (i = 0; i < lr->num_lines; i++) { in linereq_free()
1759 line = &lr->lines[i]; in linereq_free()
1760 if (!line->desc) in linereq_free()
1766 gpiod_free(line->desc); in linereq_free()
1768 kfifo_free(&lr->events); in linereq_free()
1769 kfree(lr->label); in linereq_free()
1770 gpio_device_put(lr->gdev); in linereq_free()
1776 struct linereq *lr = file->private_data; in linereq_release()
1785 struct linereq *lr = file->private_data; in linereq_show_fdinfo()
1786 struct device *dev = &lr->gdev->dev; in linereq_show_fdinfo()
1789 seq_printf(out, "gpio-chip:\t%s\n", dev_name(dev)); in linereq_show_fdinfo()
1791 for (i = 0; i < lr->num_lines; i++) in linereq_show_fdinfo()
1792 seq_printf(out, "gpio-line:\t%d\n", in linereq_show_fdinfo()
1793 gpio_chip_hwgpio(lr->lines[i].desc)); in linereq_show_fdinfo()
1823 return -EFAULT; in linereq_create()
1826 return -EINVAL; in linereq_create()
1829 return -EINVAL; in linereq_create()
1838 return -ENOMEM; in linereq_create()
1840 lr->gdev = gpio_device_get(gdev); in linereq_create()
1843 lr->lines[i].req = lr; in linereq_create()
1844 WRITE_ONCE(lr->lines[i].sw_debounced, 0); in linereq_create()
1845 INIT_DELAYED_WORK(&lr->lines[i].work, debounce_work_func); in linereq_create()
1850 lr->label = kstrndup(ulr.consumer, sizeof(ulr.consumer) - 1, in linereq_create()
1852 if (!lr->label) { in linereq_create()
1853 ret = -ENOMEM; in linereq_create()
1858 mutex_init(&lr->config_mutex); in linereq_create()
1859 init_waitqueue_head(&lr->wait); in linereq_create()
1860 lr->event_buffer_size = ulr.event_buffer_size; in linereq_create()
1861 if (lr->event_buffer_size == 0) in linereq_create()
1862 lr->event_buffer_size = ulr.num_lines * 16; in linereq_create()
1863 else if (lr->event_buffer_size > GPIO_V2_LINES_MAX * 16) in linereq_create()
1864 lr->event_buffer_size = GPIO_V2_LINES_MAX * 16; in linereq_create()
1866 atomic_set(&lr->seqno, 0); in linereq_create()
1867 lr->num_lines = ulr.num_lines; in linereq_create()
1872 struct gpio_desc *desc = gpiochip_get_desc(gdev->chip, offset); in linereq_create()
1879 ret = gpiod_request_user(desc, lr->label); in linereq_create()
1883 lr->lines[i].desc = desc; in linereq_create()
1885 gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags); in linereq_create()
1907 ret = edge_detector_setup(&lr->lines[i], lc, i, in linereq_create()
1913 lr->lines[i].edflags = edflags; in linereq_create()
1917 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linereq_create()
1921 lr->device_unregistered_nb.notifier_call = linereq_unregistered_notify; in linereq_create()
1922 ret = blocking_notifier_chain_register(&gdev->device_notifier, in linereq_create()
1923 &lr->device_unregistered_nb); in linereq_create()
1933 file = anon_inode_getfile("gpio-line", &line_fileops, lr, in linereq_create()
1948 return -EFAULT; in linereq_create()
1953 dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", in linereq_create()
1954 lr->num_lines); in linereq_create()
1972 * struct lineevent_state - contains the state of a userspace event
2004 struct lineevent_state *le = file->private_data; in lineevent_poll_unlocked()
2007 if (!le->gdev->chip) in lineevent_poll_unlocked()
2010 poll_wait(file, &le->wait, wait); in lineevent_poll_unlocked()
2012 if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock)) in lineevent_poll_unlocked()
2021 struct lineevent_state *le = file->private_data; in lineevent_poll()
2023 return call_poll_locked(file, wait, le->gdev, lineevent_poll_unlocked); in lineevent_poll()
2032 wake_up_poll(&le->wait, EPOLLIN | EPOLLERR); in lineevent_unregistered_notify()
2045 struct lineevent_state *le = file->private_data; in lineevent_read_unlocked()
2051 if (!le->gdev->chip) in lineevent_read_unlocked()
2052 return -ENODEV; in lineevent_read_unlocked()
2068 return -EINVAL; in lineevent_read_unlocked()
2071 spin_lock(&le->wait.lock); in lineevent_read_unlocked()
2072 if (kfifo_is_empty(&le->events)) { in lineevent_read_unlocked()
2074 spin_unlock(&le->wait.lock); in lineevent_read_unlocked()
2078 if (file->f_flags & O_NONBLOCK) { in lineevent_read_unlocked()
2079 spin_unlock(&le->wait.lock); in lineevent_read_unlocked()
2080 return -EAGAIN; in lineevent_read_unlocked()
2083 ret = wait_event_interruptible_locked(le->wait, in lineevent_read_unlocked()
2084 !kfifo_is_empty(&le->events)); in lineevent_read_unlocked()
2086 spin_unlock(&le->wait.lock); in lineevent_read_unlocked()
2091 ret = kfifo_out(&le->events, &ge, 1); in lineevent_read_unlocked()
2092 spin_unlock(&le->wait.lock); in lineevent_read_unlocked()
2095 * This should never happen - we were holding the lock in lineevent_read_unlocked()
2099 ret = -EIO; in lineevent_read_unlocked()
2104 return -EFAULT; in lineevent_read_unlocked()
2114 struct lineevent_state *le = file->private_data; in lineevent_read()
2116 return call_read_locked(file, buf, count, f_ps, le->gdev, in lineevent_read()
2122 if (le->device_unregistered_nb.notifier_call) in lineevent_free()
2123 blocking_notifier_chain_unregister(&le->gdev->device_notifier, in lineevent_free()
2124 &le->device_unregistered_nb); in lineevent_free()
2125 if (le->irq) in lineevent_free()
2126 free_irq_label(free_irq(le->irq, le)); in lineevent_free()
2127 if (le->desc) in lineevent_free()
2128 gpiod_free(le->desc); in lineevent_free()
2129 kfree(le->label); in lineevent_free()
2130 gpio_device_put(le->gdev); in lineevent_free()
2136 lineevent_free(file->private_data); in lineevent_release()
2143 struct lineevent_state *le = file->private_data; in lineevent_ioctl_unlocked()
2147 if (!le->gdev->chip) in lineevent_ioctl_unlocked()
2148 return -ENODEV; in lineevent_ioctl_unlocked()
2159 val = gpiod_get_value_cansleep(le->desc); in lineevent_ioctl_unlocked()
2165 return -EFAULT; in lineevent_ioctl_unlocked()
2169 return -EINVAL; in lineevent_ioctl_unlocked()
2175 struct lineevent_state *le = file->private_data; in lineevent_ioctl()
2177 return call_ioctl_locked(file, cmd, arg, le->gdev, in lineevent_ioctl()
2214 if (!le->timestamp) in lineevent_irq_thread()
2217 ge.timestamp = le->timestamp; in lineevent_irq_thread()
2219 if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE in lineevent_irq_thread()
2220 && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { in lineevent_irq_thread()
2221 int level = gpiod_get_value_cansleep(le->desc); in lineevent_irq_thread()
2224 /* Emit low-to-high event */ in lineevent_irq_thread()
2227 /* Emit high-to-low event */ in lineevent_irq_thread()
2229 } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) { in lineevent_irq_thread()
2230 /* Emit low-to-high event */ in lineevent_irq_thread()
2232 } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) { in lineevent_irq_thread()
2233 /* Emit high-to-low event */ in lineevent_irq_thread()
2239 ret = kfifo_in_spinlocked_noirqsave(&le->events, &ge, in lineevent_irq_thread()
2240 1, &le->wait.lock); in lineevent_irq_thread()
2242 wake_up_poll(&le->wait, EPOLLIN); in lineevent_irq_thread()
2244 pr_debug_ratelimited("event FIFO is full - event dropped\n"); in lineevent_irq_thread()
2257 le->timestamp = ktime_get_ns(); in lineevent_irq_handler()
2277 return -EFAULT; in lineevent_create()
2283 desc = gpiochip_get_desc(gdev->chip, offset); in lineevent_create()
2290 return -EINVAL; in lineevent_create()
2296 return -EINVAL; in lineevent_create()
2304 return -EINVAL; in lineevent_create()
2308 return -ENOMEM; in lineevent_create()
2309 le->gdev = gpio_device_get(gdev); in lineevent_create()
2313 le->label = kstrndup(eventreq.consumer_label, in lineevent_create()
2314 sizeof(eventreq.consumer_label) - 1, in lineevent_create()
2316 if (!le->label) { in lineevent_create()
2317 ret = -ENOMEM; in lineevent_create()
2322 ret = gpiod_request_user(desc, le->label); in lineevent_create()
2325 le->desc = desc; in lineevent_create()
2326 le->eflags = eflags; in lineevent_create()
2328 linehandle_flags_to_desc_flags(lflags, &desc->flags); in lineevent_create()
2338 ret = -ENODEV; in lineevent_create()
2343 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? in lineevent_create()
2346 irqflags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? in lineevent_create()
2350 INIT_KFIFO(le->events); in lineevent_create()
2351 init_waitqueue_head(&le->wait); in lineevent_create()
2353 le->device_unregistered_nb.notifier_call = lineevent_unregistered_notify; in lineevent_create()
2354 ret = blocking_notifier_chain_register(&gdev->device_notifier, in lineevent_create()
2355 &le->device_unregistered_nb); in lineevent_create()
2359 label = make_irq_label(le->label); in lineevent_create()
2377 le->irq = irq; in lineevent_create()
2385 file = anon_inode_getfile("gpio-event", in lineevent_create()
2402 return -EFAULT; in lineevent_create()
2419 u64 flagsv2 = info_v2->flags; in gpio_v2_line_info_to_v1()
2421 memcpy(info_v1->name, info_v2->name, sizeof(info_v1->name)); in gpio_v2_line_info_to_v1()
2422 memcpy(info_v1->consumer, info_v2->consumer, sizeof(info_v1->consumer)); in gpio_v2_line_info_to_v1()
2423 info_v1->line_offset = info_v2->offset; in gpio_v2_line_info_to_v1()
2424 info_v1->flags = 0; in gpio_v2_line_info_to_v1()
2427 info_v1->flags |= GPIOLINE_FLAG_KERNEL; in gpio_v2_line_info_to_v1()
2430 info_v1->flags |= GPIOLINE_FLAG_IS_OUT; in gpio_v2_line_info_to_v1()
2433 info_v1->flags |= GPIOLINE_FLAG_ACTIVE_LOW; in gpio_v2_line_info_to_v1()
2436 info_v1->flags |= GPIOLINE_FLAG_OPEN_DRAIN; in gpio_v2_line_info_to_v1()
2438 info_v1->flags |= GPIOLINE_FLAG_OPEN_SOURCE; in gpio_v2_line_info_to_v1()
2441 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_UP; in gpio_v2_line_info_to_v1()
2443 info_v1->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN; in gpio_v2_line_info_to_v1()
2445 info_v1->flags |= GPIOLINE_FLAG_BIAS_DISABLE; in gpio_v2_line_info_to_v1()
2453 gpio_v2_line_info_to_v1(&lic_v2->info, &lic_v1->info); in gpio_v2_line_info_changed_to_v1()
2454 lic_v1->timestamp = lic_v2->timestamp_ns; in gpio_v2_line_info_changed_to_v1()
2455 lic_v1->event_type = lic_v2->event_type; in gpio_v2_line_info_changed_to_v1()
2463 struct gpio_chip *gc = desc->gdev->chip; in gpio_desc_to_lineinfo()
2468 info->offset = gpio_chip_hwgpio(desc); in gpio_desc_to_lineinfo()
2474 * FIXME: find a non-racy way to retrieve this information. Maybe a in gpio_desc_to_lineinfo()
2478 pinctrl_gpio_can_use_line(gc->base + info->offset); in gpio_desc_to_lineinfo()
2482 if (desc->name) in gpio_desc_to_lineinfo()
2483 strscpy(info->name, desc->name, sizeof(info->name)); in gpio_desc_to_lineinfo()
2485 if (desc->label) in gpio_desc_to_lineinfo()
2486 strscpy(info->consumer, desc->label, sizeof(info->consumer)); in gpio_desc_to_lineinfo()
2492 info->flags = 0; in gpio_desc_to_lineinfo()
2493 if (test_bit(FLAG_REQUESTED, &desc->flags) || in gpio_desc_to_lineinfo()
2494 test_bit(FLAG_IS_HOGGED, &desc->flags) || in gpio_desc_to_lineinfo()
2495 test_bit(FLAG_USED_AS_IRQ, &desc->flags) || in gpio_desc_to_lineinfo()
2496 test_bit(FLAG_EXPORT, &desc->flags) || in gpio_desc_to_lineinfo()
2497 test_bit(FLAG_SYSFS, &desc->flags) || in gpio_desc_to_lineinfo()
2498 !gpiochip_line_is_valid(gc, info->offset) || in gpio_desc_to_lineinfo()
2500 info->flags |= GPIO_V2_LINE_FLAG_USED; in gpio_desc_to_lineinfo()
2502 if (test_bit(FLAG_IS_OUT, &desc->flags)) in gpio_desc_to_lineinfo()
2503 info->flags |= GPIO_V2_LINE_FLAG_OUTPUT; in gpio_desc_to_lineinfo()
2505 info->flags |= GPIO_V2_LINE_FLAG_INPUT; in gpio_desc_to_lineinfo()
2507 if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) in gpio_desc_to_lineinfo()
2508 info->flags |= GPIO_V2_LINE_FLAG_ACTIVE_LOW; in gpio_desc_to_lineinfo()
2510 if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) in gpio_desc_to_lineinfo()
2511 info->flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN; in gpio_desc_to_lineinfo()
2512 if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) in gpio_desc_to_lineinfo()
2513 info->flags |= GPIO_V2_LINE_FLAG_OPEN_SOURCE; in gpio_desc_to_lineinfo()
2515 if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) in gpio_desc_to_lineinfo()
2516 info->flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED; in gpio_desc_to_lineinfo()
2517 if (test_bit(FLAG_PULL_DOWN, &desc->flags)) in gpio_desc_to_lineinfo()
2518 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN; in gpio_desc_to_lineinfo()
2519 if (test_bit(FLAG_PULL_UP, &desc->flags)) in gpio_desc_to_lineinfo()
2520 info->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP; in gpio_desc_to_lineinfo()
2522 if (test_bit(FLAG_EDGE_RISING, &desc->flags)) in gpio_desc_to_lineinfo()
2523 info->flags |= GPIO_V2_LINE_FLAG_EDGE_RISING; in gpio_desc_to_lineinfo()
2524 if (test_bit(FLAG_EDGE_FALLING, &desc->flags)) in gpio_desc_to_lineinfo()
2525 info->flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; in gpio_desc_to_lineinfo()
2527 if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &desc->flags)) in gpio_desc_to_lineinfo()
2528 info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME; in gpio_desc_to_lineinfo()
2529 else if (test_bit(FLAG_EVENT_CLOCK_HTE, &desc->flags)) in gpio_desc_to_lineinfo()
2530 info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE; in gpio_desc_to_lineinfo()
2549 struct gpio_device *gdev = cdev->gdev; in chipinfo_get()
2554 strscpy(chipinfo.name, dev_name(&gdev->dev), sizeof(chipinfo.name)); in chipinfo_get()
2555 strscpy(chipinfo.label, gdev->label, sizeof(chipinfo.label)); in chipinfo_get()
2556 chipinfo.lines = gdev->ngpio; in chipinfo_get()
2558 return -EFAULT; in chipinfo_get()
2569 int abiv = atomic_cmpxchg(&cdata->watch_abi_version, 0, version); in lineinfo_ensure_abi_version()
2585 return -EFAULT; in lineinfo_get_v1()
2588 desc = gpiochip_get_desc(cdev->gdev->chip, lineinfo.line_offset); in lineinfo_get_v1()
2594 return -EPERM; in lineinfo_get_v1()
2596 if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines)) in lineinfo_get_v1()
2597 return -EBUSY; in lineinfo_get_v1()
2605 clear_bit(lineinfo.line_offset, cdev->watched_lines); in lineinfo_get_v1()
2606 return -EFAULT; in lineinfo_get_v1()
2620 return -EFAULT; in lineinfo_get()
2623 return -EINVAL; in lineinfo_get()
2625 desc = gpiochip_get_desc(cdev->gdev->chip, lineinfo.offset); in lineinfo_get()
2632 return -EPERM; in lineinfo_get()
2634 if (test_and_set_bit(lineinfo.offset, cdev->watched_lines)) in lineinfo_get()
2635 return -EBUSY; in lineinfo_get()
2642 clear_bit(lineinfo.offset, cdev->watched_lines); in lineinfo_get()
2643 return -EFAULT; in lineinfo_get()
2654 return -EFAULT; in lineinfo_unwatch()
2656 if (offset >= cdev->gdev->ngpio) in lineinfo_unwatch()
2657 return -EINVAL; in lineinfo_unwatch()
2659 if (!test_and_clear_bit(offset, cdev->watched_lines)) in lineinfo_unwatch()
2660 return -EBUSY; in lineinfo_unwatch()
2667 struct gpio_chardev_data *cdev = file->private_data; in gpio_ioctl_unlocked()
2668 struct gpio_device *gdev = cdev->gdev; in gpio_ioctl_unlocked()
2672 if (!gdev->chip) in gpio_ioctl_unlocked()
2673 return -ENODEV; in gpio_ioctl_unlocked()
2698 return -EINVAL; in gpio_ioctl_unlocked()
2703 * gpio_ioctl() - ioctl handler for the GPIO chardev
2707 struct gpio_chardev_data *cdev = file->private_data; in gpio_ioctl()
2709 return call_ioctl_locked(file, cmd, arg, cdev->gdev, in gpio_ioctl()
2726 struct gpio_v2_line_info_changed chg; in lineinfo_changed_notify() local
2730 if (!test_bit(gpio_chip_hwgpio(desc), cdev->watched_lines)) in lineinfo_changed_notify()
2733 memset(&chg, 0, sizeof(chg)); in lineinfo_changed_notify()
2734 chg.event_type = action; in lineinfo_changed_notify()
2735 chg.timestamp_ns = ktime_get_ns(); in lineinfo_changed_notify()
2736 gpio_desc_to_lineinfo(desc, &chg.info); in lineinfo_changed_notify()
2737 supinfo_to_lineinfo(desc, &chg.info); in lineinfo_changed_notify()
2739 ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock); in lineinfo_changed_notify()
2741 wake_up_poll(&cdev->wait, EPOLLIN); in lineinfo_changed_notify()
2743 pr_debug_ratelimited("lineinfo event FIFO is full - event dropped\n"); in lineinfo_changed_notify()
2755 wake_up_poll(&cdev->wait, EPOLLIN | EPOLLERR); in gpio_device_unregistered_notify()
2763 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_poll_unlocked()
2766 if (!cdev->gdev->chip) in lineinfo_watch_poll_unlocked()
2769 poll_wait(file, &cdev->wait, pollt); in lineinfo_watch_poll_unlocked()
2771 if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events, in lineinfo_watch_poll_unlocked()
2772 &cdev->wait.lock)) in lineinfo_watch_poll_unlocked()
2781 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_poll()
2783 return call_poll_locked(file, pollt, cdev->gdev, in lineinfo_watch_poll()
2790 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_read_unlocked()
2796 if (!cdev->gdev->chip) in lineinfo_watch_read_unlocked()
2797 return -ENODEV; in lineinfo_watch_read_unlocked()
2802 return -EINVAL; in lineinfo_watch_read_unlocked()
2806 spin_lock(&cdev->wait.lock); in lineinfo_watch_read_unlocked()
2807 if (kfifo_is_empty(&cdev->events)) { in lineinfo_watch_read_unlocked()
2809 spin_unlock(&cdev->wait.lock); in lineinfo_watch_read_unlocked()
2813 if (file->f_flags & O_NONBLOCK) { in lineinfo_watch_read_unlocked()
2814 spin_unlock(&cdev->wait.lock); in lineinfo_watch_read_unlocked()
2815 return -EAGAIN; in lineinfo_watch_read_unlocked()
2818 ret = wait_event_interruptible_locked(cdev->wait, in lineinfo_watch_read_unlocked()
2819 !kfifo_is_empty(&cdev->events)); in lineinfo_watch_read_unlocked()
2821 spin_unlock(&cdev->wait.lock); in lineinfo_watch_read_unlocked()
2827 if (atomic_read(&cdev->watch_abi_version) == 2) in lineinfo_watch_read_unlocked()
2832 spin_unlock(&cdev->wait.lock); in lineinfo_watch_read_unlocked()
2833 return -EINVAL; in lineinfo_watch_read_unlocked()
2836 ret = kfifo_out(&cdev->events, &event, 1); in lineinfo_watch_read_unlocked()
2837 spin_unlock(&cdev->wait.lock); in lineinfo_watch_read_unlocked()
2839 ret = -EIO; in lineinfo_watch_read_unlocked()
2847 return -EFAULT; in lineinfo_watch_read_unlocked()
2854 return -EFAULT; in lineinfo_watch_read_unlocked()
2858 return -EFAULT; in lineinfo_watch_read_unlocked()
2869 struct gpio_chardev_data *cdev = file->private_data; in lineinfo_watch_read()
2871 return call_read_locked(file, buf, count, off, cdev->gdev, in lineinfo_watch_read()
2876 * gpio_chrdev_open() - open the chardev for ioctl operations
2883 struct gpio_device *gdev = container_of(inode->i_cdev, in gpio_chrdev_open()
2886 int ret = -ENOMEM; in gpio_chrdev_open()
2888 down_read(&gdev->sem); in gpio_chrdev_open()
2891 if (!gdev->chip) { in gpio_chrdev_open()
2892 ret = -ENODEV; in gpio_chrdev_open()
2900 cdev->watched_lines = bitmap_zalloc(gdev->chip->ngpio, GFP_KERNEL); in gpio_chrdev_open()
2901 if (!cdev->watched_lines) in gpio_chrdev_open()
2904 init_waitqueue_head(&cdev->wait); in gpio_chrdev_open()
2905 INIT_KFIFO(cdev->events); in gpio_chrdev_open()
2906 cdev->gdev = gpio_device_get(gdev); in gpio_chrdev_open()
2908 cdev->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify; in gpio_chrdev_open()
2909 ret = blocking_notifier_chain_register(&gdev->line_state_notifier, in gpio_chrdev_open()
2910 &cdev->lineinfo_changed_nb); in gpio_chrdev_open()
2914 cdev->device_unregistered_nb.notifier_call = in gpio_chrdev_open()
2916 ret = blocking_notifier_chain_register(&gdev->device_notifier, in gpio_chrdev_open()
2917 &cdev->device_unregistered_nb); in gpio_chrdev_open()
2921 file->private_data = cdev; in gpio_chrdev_open()
2927 up_read(&gdev->sem); in gpio_chrdev_open()
2932 blocking_notifier_chain_unregister(&gdev->device_notifier, in gpio_chrdev_open()
2933 &cdev->device_unregistered_nb); in gpio_chrdev_open()
2935 blocking_notifier_chain_unregister(&gdev->line_state_notifier, in gpio_chrdev_open()
2936 &cdev->lineinfo_changed_nb); in gpio_chrdev_open()
2939 bitmap_free(cdev->watched_lines); in gpio_chrdev_open()
2943 up_read(&gdev->sem); in gpio_chrdev_open()
2948 * gpio_chrdev_release() - close chardev after ioctl operations
2955 struct gpio_chardev_data *cdev = file->private_data; in gpio_chrdev_release()
2956 struct gpio_device *gdev = cdev->gdev; in gpio_chrdev_release()
2958 blocking_notifier_chain_unregister(&gdev->device_notifier, in gpio_chrdev_release()
2959 &cdev->device_unregistered_nb); in gpio_chrdev_release()
2960 blocking_notifier_chain_unregister(&gdev->line_state_notifier, in gpio_chrdev_release()
2961 &cdev->lineinfo_changed_nb); in gpio_chrdev_release()
2962 bitmap_free(cdev->watched_lines); in gpio_chrdev_release()
2986 cdev_init(&gdev->chrdev, &gpio_fileops); in gpiolib_cdev_register()
2987 gdev->chrdev.owner = THIS_MODULE; in gpiolib_cdev_register()
2988 gdev->dev.devt = MKDEV(MAJOR(devt), gdev->id); in gpiolib_cdev_register()
2990 ret = cdev_device_add(&gdev->chrdev, &gdev->dev); in gpiolib_cdev_register()
2994 chip_dbg(gdev->chip, "added GPIO chardev (%d:%d)\n", in gpiolib_cdev_register()
2995 MAJOR(devt), gdev->id); in gpiolib_cdev_register()
3002 cdev_device_del(&gdev->chrdev, &gdev->dev); in gpiolib_cdev_unregister()
3003 blocking_notifier_call_chain(&gdev->device_notifier, 0, NULL); in gpiolib_cdev_unregister()