On Tue, Sep 15, 2020 at 01:39:41PM +0300, Andy Shevchenko wrote: > On Wed, Sep 9, 2020 at 1:33 PM Kent Gibson <warthog618@xxxxxxxxx> wrote: > > > > Add support for edge detection to lines requested using > > GPIO_V2_GET_LINE_IOCTL. > > > > The edge_detector implementation is based on the v1 lineevent > > implementation. > > ... > [snip] > > + > > + /* > > + * We may be running from a nested threaded interrupt in which case > > + * we didn't get the timestamp from edge_irq_handler(). > > + */ > > > + if (!line->timestamp) { > > Can it be positive conditional? > Not sure what you mean - switch the order of the if/else? > > + le.timestamp = ktime_get_ns(); > > + if (lr->num_lines != 1) > > + line->req_seqno = atomic_inc_return(&lr->seqno); > > + } else { > > + le.timestamp = line->timestamp; > > + } > > + line->timestamp = 0; > > + > > + if (line->eflags == (GPIO_V2_LINE_FLAG_EDGE_RISING | > > + GPIO_V2_LINE_FLAG_EDGE_FALLING)) { > > + int level = gpiod_get_value_cansleep(line->desc); > > + > > + if (level) > > + /* Emit low-to-high event */ > > + le.id = GPIO_V2_LINE_EVENT_RISING_EDGE; > > + else > > + /* Emit high-to-low event */ > > + le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE; > > + } else if (line->eflags == GPIO_V2_LINE_FLAG_EDGE_RISING) { > > + /* Emit low-to-high event */ > > + le.id = GPIO_V2_LINE_EVENT_RISING_EDGE; > > + } else if (line->eflags == GPIO_V2_LINE_FLAG_EDGE_FALLING) { > > + /* Emit high-to-low event */ > > + le.id = GPIO_V2_LINE_EVENT_FALLING_EDGE; > > + } else { > > + return IRQ_NONE; > > + } > > + line->line_seqno++; > > + le.line_seqno = line->line_seqno; > > + le.seqno = (lr->num_lines == 1) ? le.line_seqno : line->req_seqno; > > + le.offset = gpio_chip_hwgpio(line->desc); > > + > > + ret = kfifo_in_spinlocked_noirqsave(&lr->events, &le, > > + 1, &lr->wait.lock); > > + if (ret) > > + wake_up_poll(&lr->wait, EPOLLIN); > > + else > > > + pr_debug_ratelimited("event FIFO is full - event dropped\n"); > > Oh, can we really avoid printf() in IRQ context? > Even in the IRQ thread? Would a tracepoint be preferable? Btw, this is drawn from the v1 implmentation. > > + > > +static void edge_detector_stop(struct line *line) > > +{ > > > + if (line->irq) { > > + free_irq(line->irq, line); > > + line->irq = 0; > > + } > > Perhaps > > if (!line->irq) > return; > > ? > No - the function is extended in subsequent patches. I usually make a note of cases like this in the commentary, but missed this one. > > + if (!eflags) > > + return 0; > > + > > + irq = gpiod_to_irq(line->desc); > > + if (irq <= 0) > > > + return -ENODEV; > > Why shadowing actual error code? > Another one drawn from the v1 implementation, so not sure. gpiod_to_irq() can potentially return EINVAL, which is definitely not appropriate to return, or ENXIO, which is actually more appropriate?? Cheers, Kent.