in counter-chrdev.c [532:572]
void counter_push_event(struct counter_device *const counter, const u8 event,
const u8 channel)
{
struct counter_event ev;
unsigned int copied = 0;
unsigned long flags;
struct counter_event_node *event_node;
struct counter_comp_node *comp_node;
ev.timestamp = ktime_get_ns();
ev.watch.event = event;
ev.watch.channel = channel;
/* Could be in an interrupt context, so use a spin lock */
spin_lock_irqsave(&counter->events_list_lock, flags);
/* Search for event in the list */
list_for_each_entry(event_node, &counter->events_list, l)
if (event_node->event == event &&
event_node->channel == channel)
break;
/* If event is not in the list */
if (&event_node->l == &counter->events_list)
goto exit_early;
/* Read and queue relevant comp for userspace */
list_for_each_entry(comp_node, &event_node->comp_list, l) {
ev.watch.component = comp_node->component;
ev.status = -counter_get_data(counter, comp_node, &ev.value);
copied += kfifo_in_spinlocked_noirqsave(&counter->events, &ev,
1, &counter->events_in_lock);
}
exit_early:
spin_unlock_irqrestore(&counter->events_list_lock, flags);
if (copied)
wake_up_poll(&counter->events_wait, EPOLLIN);
}