Lines Matching full:line

107  * GPIO line handle management
276 * All line descriptors were created at once with the same in linehandle_ioctl_unlocked()
407 * or output, else the line will be treated "as is". in linehandle_create()
423 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linehandle_create()
469 * struct line - contains the state of a requested line
471 * @desc: the GPIO descriptor for this line.
472 * @req: the corresponding line request
479 * events for the corresponding line request. This is drawn from the @req.
481 * events for this line.
485 * @level: the current debounced physical level of the line
487 * @raw_level: the line level at the time of event
491 struct line { struct
550 * HTE provider sets line level at the time of event. The valid argument
555 * when sw_debounce is set on HTE enabled line, this is running argument
560 * when sw_debounce is set on HTE enabled line, this variable records argument
571 * A line is determined to contain supplemental information by argument
579 * struct linereq - contains the state of a userspace line request
580 * @gdev: the GPIO device the line request pertains to
588 * this line request. Note that this is not used when @num_lines is 1, as
593 * @lines: the lines held by this line request, with @num_lines elements.
605 struct line lines[];
608 static void supinfo_insert(struct line *line) in supinfo_insert() argument
611 struct line *entry; in supinfo_insert()
616 entry = container_of(*new, struct line, node); in supinfo_insert()
619 if (line->desc < entry->desc) { in supinfo_insert()
621 } else if (line->desc > entry->desc) { in supinfo_insert()
625 WARN(1, "duplicate line inserted"); 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()
634 static void supinfo_erase(struct line *line) in supinfo_erase() argument
638 rb_erase(&line->node, &supinfo_tree); in supinfo_erase()
641 static struct line *supinfo_find(struct gpio_desc *desc) in supinfo_find()
644 struct line *line; in supinfo_find() local
647 line = container_of(node, struct line, node); in supinfo_find()
648 if (desc < line->desc) in supinfo_find()
650 else if (desc > line->desc) in supinfo_find()
653 return line; in supinfo_find()
662 struct line *line; in supinfo_to_lineinfo() local
666 line = supinfo_find(desc); in supinfo_to_lineinfo()
667 if (!line) in supinfo_to_lineinfo()
672 attr->debounce_period_us = READ_ONCE(line->debounce_period_us); in supinfo_to_lineinfo()
676 static inline bool line_has_supinfo(struct line *line) in line_has_supinfo() argument
678 return READ_ONCE(line->debounce_period_us); in line_has_supinfo()
684 * Called indirectly by linereq_create() or linereq_set_config() so line
687 static void line_set_debounce_period(struct line *line, in line_set_debounce_period() argument
690 bool was_suppl = line_has_supinfo(line); in line_set_debounce_period()
692 WRITE_ONCE(line->debounce_period_us, debounce_period_us); in line_set_debounce_period()
695 if (line_has_supinfo(line) == was_suppl) in line_set_debounce_period()
700 supinfo_erase(line); in line_set_debounce_period()
702 supinfo_insert(line); in line_set_debounce_period()
768 static u64 line_event_timestamp(struct line *line) in line_event_timestamp() argument
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()
808 struct line *line; in process_hw_ts_thread() local
817 line = p; in process_hw_ts_thread()
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()
856 struct line *line; in process_hw_ts() local
863 line = p; in process_hw_ts()
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()
880 line->req_seqno = atomic_add_return(diff_seqno, in process_hw_ts()
889 static int hte_edge_setup(struct line *line, u64 eflags) in hte_edge_setup() argument
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()
914 line); in hte_edge_setup()
919 static int hte_edge_setup(struct line *line, u64 eflags) in hte_edge_setup() argument
927 struct line *line = p; in edge_irq_thread() local
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()
942 le.timestamp_ns = line_event_timestamp(line); 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()
973 struct line *line = p; in edge_irq_handler() local
974 struct linereq *lr = line->req; in edge_irq_handler()
980 line->timestamp_ns = line_event_timestamp(line); in edge_irq_handler()
983 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_handler()
991 static bool debounced_value(struct line *line) in debounced_value() argument
1000 value = READ_ONCE(line->level); in debounced_value()
1002 if (test_bit(FLAG_ACTIVE_LOW, &line->desc->flags)) in debounced_value()
1010 struct line *line = p; in debounce_irq_handler() local
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()
1021 struct line *line = container_of(work, struct line, work.work); in debounce_work_func() local
1023 u64 eflags, edflags = READ_ONCE(line->edflags); 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()
1034 pr_debug_ratelimited("debouncer failed to read line value\n"); 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()
1060 lr = line->req; in debounce_work_func()
1061 le.timestamp_ns = line_event_timestamp(line); 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()
1076 line->line_seqno++; in debounce_work_func()
1077 le.line_seqno = line->line_seqno; in debounce_work_func()
1087 static int debounce_setup(struct line *line, unsigned int debounce_period_us) in debounce_setup() argument
1094 ret = gpiod_set_debounce(line->desc, debounce_period_us); in debounce_setup()
1096 line_set_debounce_period(line, debounce_period_us); 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()
1114 label = make_irq_label(line->req->label); in debounce_setup()
1120 label, line); in debounce_setup()
1125 line->irq = irq; in debounce_setup()
1127 ret = hte_edge_setup(line, GPIO_V2_LINE_FLAG_EDGE_BOTH); in debounce_setup()
1132 WRITE_ONCE(line->level, level); in debounce_setup()
1133 WRITE_ONCE(line->sw_debounced, 1); in debounce_setup()
1166 static void edge_detector_stop(struct line *line) in edge_detector_stop() argument
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()
1181 line_set_debounce_period(line, 0); in edge_detector_stop()
1182 /* do not change line->level - see comment in debounced_value() */ in edge_detector_stop()
1185 static int edge_detector_setup(struct line *line, in edge_detector_setup() argument
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()
1204 ret = debounce_setup(line, debounce_period_us); in edge_detector_setup()
1207 line_set_debounce_period(line, debounce_period_us); in edge_detector_setup()
1211 if (!eflags || READ_ONCE(line->sw_debounced)) in edge_detector_setup()
1216 return hte_edge_setup(line, edflags); in edge_detector_setup()
1218 irq = gpiod_to_irq(line->desc); 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()
1236 irqflags, label, line); in edge_detector_setup()
1242 line->irq = irq; in edge_detector_setup()
1246 static int edge_detector_update(struct line *line, in edge_detector_update() argument
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()
1262 line_set_debounce_period(line, debounce_period_us); 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()
1282 edge_detector_stop(line); in edge_detector_update()
1284 return edge_detector_setup(line, lc, line_idx, edflags); in edge_detector_update()
1559 struct line *line; in linereq_set_config_unlocked() local
1565 line = &lr->lines[i]; in linereq_set_config_unlocked()
1579 edge_detector_stop(line); in linereq_set_config_unlocked()
1588 ret = edge_detector_update(line, lc, i, edflags); in linereq_set_config_unlocked()
1593 WRITE_ONCE(line->edflags, edflags); in linereq_set_config_unlocked()
1751 struct line *line; in linereq_free() local
1759 line = &lr->lines[i]; in linereq_free()
1760 if (!line->desc) in linereq_free()
1763 edge_detector_stop(line); in linereq_free()
1764 if (line_has_supinfo(line)) in linereq_free()
1765 supinfo_erase(line); in linereq_free()
1766 gpiod_free(line->desc); in linereq_free()
1792 seq_printf(out, "gpio-line:\t%d\n", in linereq_show_fdinfo()
1894 * or output, else the line will be treated "as is". in linereq_create()
1917 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linereq_create()
1933 file = anon_inode_getfile("gpio-line", &line_fileops, lr, in linereq_create()
1968 * GPIO line event management
1976 * @eflags: the event flags this line was requested with
2151 * We can get the value for an event line but not set it, in lineevent_ioctl_unlocked()