Lines Matching full:line

59  * GPIO line handle management
173 * or output, else the line will be treated "as is". in linehandle_set_config()
223 * All line descriptors were created at once with the same in linehandle_ioctl()
346 * or output, else the line will be treated "as is". in linehandle_create()
363 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linehandle_create()
409 * struct line - contains the state of a requested line
410 * @desc: the GPIO descriptor for this line.
411 * @req: the corresponding line request
418 * events for the corresponding line request. This is drawn from the @req.
420 * events for this line.
423 * @level: the current debounced physical level of the line
425 * @raw_level: the line level at the time of event
429 struct line { struct
478 * HTE provider sets line level at the time of event. The valid argument
483 * when sw_debounce is set on HTE enabled line, this is running argument
488 * when sw_debounce is set on HTE enabled line, this variable records argument
496 * struct linereq - contains the state of a userspace line request argument
497 * @gdev: the GPIO device the line request pertains to
504 * this line request. Note that this is not used when @num_lines is 1, as
508 * @lines: the lines held by this line request, with @num_lines elements.
519 struct line lines[];
574 static u64 line_event_timestamp(struct line *line) in line_event_timestamp() argument
576 if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &line->desc->flags)) in line_event_timestamp()
579 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags)) in line_event_timestamp()
580 return line->timestamp_ns; in line_event_timestamp()
595 struct line *line; in process_hw_ts_thread() local
604 line = p; in process_hw_ts_thread()
605 lr = line->req; in process_hw_ts_thread()
609 le.timestamp_ns = line->timestamp_ns; in process_hw_ts_thread()
610 edflags = READ_ONCE(line->edflags); in process_hw_ts_thread()
614 level = (line->raw_level >= 0) ? in process_hw_ts_thread()
615 line->raw_level : in process_hw_ts_thread()
616 gpiod_get_raw_value_cansleep(line->desc); in process_hw_ts_thread()
632 le.line_seqno = line->line_seqno; in process_hw_ts_thread()
633 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in process_hw_ts_thread()
634 le.offset = gpio_chip_hwgpio(line->desc); in process_hw_ts_thread()
643 struct line *line; in process_hw_ts() local
650 line = p; in process_hw_ts()
651 line->timestamp_ns = ts->tsc; in process_hw_ts()
652 line->raw_level = ts->raw_level; in process_hw_ts()
653 lr = line->req; in process_hw_ts()
655 if (READ_ONCE(line->sw_debounced)) { in process_hw_ts()
656 line->total_discard_seq++; in process_hw_ts()
657 line->last_seqno = ts->seq; in process_hw_ts()
658 mod_delayed_work(system_wq, &line->work, in process_hw_ts()
659 usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us))); in process_hw_ts()
661 if (unlikely(ts->seq < line->line_seqno)) in process_hw_ts()
664 diff_seqno = ts->seq - line->line_seqno; in process_hw_ts()
665 line->line_seqno = ts->seq; in process_hw_ts()
667 line->req_seqno = atomic_add_return(diff_seqno, in process_hw_ts()
676 static int hte_edge_setup(struct line *line, u64 eflags) in hte_edge_setup() argument
680 struct hte_ts_desc *hdesc = &line->hdesc; in hte_edge_setup()
683 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
687 flags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in hte_edge_setup()
691 line->total_discard_seq = 0; in hte_edge_setup()
693 hte_init_line_attr(hdesc, desc_to_gpio(line->desc), flags, NULL, in hte_edge_setup()
694 line->desc); in hte_edge_setup()
701 line); in hte_edge_setup()
706 static int hte_edge_setup(struct line *line, u64 eflags) in hte_edge_setup() argument
714 struct line *line = p; in edge_irq_thread() local
715 struct linereq *lr = line->req; in edge_irq_thread()
721 if (line->timestamp_ns) { in edge_irq_thread()
722 le.timestamp_ns = line->timestamp_ns; in edge_irq_thread()
729 le.timestamp_ns = line_event_timestamp(line); in edge_irq_thread()
731 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_thread()
733 line->timestamp_ns = 0; in edge_irq_thread()
735 switch (READ_ONCE(line->edflags) & GPIO_V2_LINE_EDGE_FLAGS) { in edge_irq_thread()
737 le.id = line_event_id(gpiod_get_value_cansleep(line->desc)); in edge_irq_thread()
748 line->line_seqno++; in edge_irq_thread()
749 le.line_seqno = line->line_seqno; in edge_irq_thread()
750 le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; in edge_irq_thread()
751 le.offset = gpio_chip_hwgpio(line->desc); in edge_irq_thread()
760 struct line *line = p; in edge_irq_handler() local
761 struct linereq *lr = line->req; in edge_irq_handler()
767 line->timestamp_ns = line_event_timestamp(line); in edge_irq_handler()
770 line->req_seqno = atomic_inc_return(&lr->seqno); in edge_irq_handler()
778 static bool debounced_value(struct line *line) in debounced_value() argument
787 value = READ_ONCE(line->level); in debounced_value()
789 if (test_bit(FLAG_ACTIVE_LOW, &line->desc->flags)) in debounced_value()
797 struct line *line = p; in debounce_irq_handler() local
799 mod_delayed_work(system_wq, &line->work, in debounce_irq_handler()
800 usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us))); in debounce_irq_handler()
808 struct line *line = container_of(work, struct line, work.work); in debounce_work_func() local
810 u64 eflags, edflags = READ_ONCE(line->edflags); in debounce_work_func()
816 level = line->raw_level; in debounce_work_func()
819 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_work_func()
821 pr_debug_ratelimited("debouncer failed to read line value\n"); in debounce_work_func()
825 if (READ_ONCE(line->level) == level) in debounce_work_func()
828 WRITE_ONCE(line->level, level); in debounce_work_func()
847 lr = line->req; in debounce_work_func()
848 le.timestamp_ns = line_event_timestamp(line); in debounce_work_func()
849 le.offset = gpio_chip_hwgpio(line->desc); in debounce_work_func()
853 line->total_discard_seq -= 1; in debounce_work_func()
854 diff_seqno = line->last_seqno - line->total_discard_seq - in debounce_work_func()
855 line->line_seqno; in debounce_work_func()
856 line->line_seqno = line->last_seqno - line->total_discard_seq; in debounce_work_func()
857 le.line_seqno = line->line_seqno; in debounce_work_func()
863 line->line_seqno++; in debounce_work_func()
864 le.line_seqno = line->line_seqno; in debounce_work_func()
874 static int debounce_setup(struct line *line, unsigned int debounce_period_us) in debounce_setup() argument
880 ret = gpiod_set_debounce(line->desc, debounce_period_us); in debounce_setup()
882 WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us); in debounce_setup()
890 level = gpiod_get_raw_value_cansleep(line->desc); in debounce_setup()
895 test_bit(FLAG_EVENT_CLOCK_HTE, &line->desc->flags))) { in debounce_setup()
896 irq = gpiod_to_irq(line->desc); in debounce_setup()
902 line->req->label, line); in debounce_setup()
905 line->irq = irq; in debounce_setup()
907 ret = hte_edge_setup(line, GPIO_V2_LINE_FLAG_EDGE_BOTH); in debounce_setup()
912 WRITE_ONCE(line->level, level); in debounce_setup()
913 WRITE_ONCE(line->sw_debounced, 1); in debounce_setup()
946 static void edge_detector_stop(struct line *line) in edge_detector_stop() argument
948 if (line->irq) { in edge_detector_stop()
949 free_irq(line->irq, line); in edge_detector_stop()
950 line->irq = 0; in edge_detector_stop()
954 if (READ_ONCE(line->edflags) & GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE) in edge_detector_stop()
955 hte_ts_put(&line->hdesc); in edge_detector_stop()
958 cancel_delayed_work_sync(&line->work); in edge_detector_stop()
959 WRITE_ONCE(line->sw_debounced, 0); in edge_detector_stop()
960 WRITE_ONCE(line->edflags, 0); in edge_detector_stop()
961 if (line->desc) in edge_detector_stop()
962 WRITE_ONCE(line->desc->debounce_period_us, 0); in edge_detector_stop()
963 /* do not change line->level - see comment in debounced_value() */ in edge_detector_stop()
966 static int edge_detector_setup(struct line *line, in edge_detector_setup() argument
976 if (eflags && !kfifo_initialized(&line->req->events)) { in edge_detector_setup()
977 ret = kfifo_alloc(&line->req->events, in edge_detector_setup()
978 line->req->event_buffer_size, GFP_KERNEL); in edge_detector_setup()
984 ret = debounce_setup(line, debounce_period_us); in edge_detector_setup()
987 WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us); in edge_detector_setup()
991 if (!eflags || READ_ONCE(line->sw_debounced)) in edge_detector_setup()
996 return hte_edge_setup(line, edflags); in edge_detector_setup()
998 irq = gpiod_to_irq(line->desc); in edge_detector_setup()
1003 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1006 irqflags |= test_bit(FLAG_ACTIVE_LOW, &line->desc->flags) ? in edge_detector_setup()
1012 irqflags, line->req->label, line); in edge_detector_setup()
1016 line->irq = irq; in edge_detector_setup()
1020 static int edge_detector_update(struct line *line, in edge_detector_update() argument
1024 u64 active_edflags = READ_ONCE(line->edflags); in edge_detector_update()
1029 (READ_ONCE(line->desc->debounce_period_us) == debounce_period_us)) in edge_detector_update()
1033 if (debounce_period_us && READ_ONCE(line->sw_debounced)) { in edge_detector_update()
1034 WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us); in edge_detector_update()
1039 if ((line->irq && !READ_ONCE(line->sw_debounced)) || in edge_detector_update()
1041 (!debounce_period_us && READ_ONCE(line->sw_debounced))) in edge_detector_update()
1042 edge_detector_stop(line); in edge_detector_update()
1044 return edge_detector_setup(line, lc, line_idx, edflags); in edge_detector_update()
1319 struct line *line; in linereq_set_config_unlocked() local
1325 line = &lr->lines[i]; in linereq_set_config_unlocked()
1332 * or output, else the line will be treated "as is". in linereq_set_config_unlocked()
1337 edge_detector_stop(line); in linereq_set_config_unlocked()
1346 ret = edge_detector_update(line, lc, i, edflags); in linereq_set_config_unlocked()
1351 WRITE_ONCE(line->edflags, edflags); in linereq_set_config_unlocked()
1510 seq_printf(out, "gpio-line:\t%d\n", in linereq_show_fdinfo()
1613 * or output, else the line will be treated "as is". in linereq_create()
1637 dev_dbg(&gdev->dev, "registered chardev handle for line %d\n", in linereq_create()
1647 file = anon_inode_getfile("gpio-line", &line_fileops, lr, in linereq_create()
1682 * GPIO line event management
1690 * @eflags: the event flags this line was requested with
1825 * We can get the value for an event line but not set it, in lineevent_ioctl()