in counter-chrdev.c [130:185]
static int counter_set_event_node(struct counter_device *const counter,
struct counter_watch *const watch,
const struct counter_comp_node *const cfg)
{
struct counter_event_node *event_node;
int err = 0;
struct counter_comp_node *comp_node;
/* Search for event in the list */
list_for_each_entry(event_node, &counter->next_events_list, l)
if (event_node->event == watch->event &&
event_node->channel == watch->channel)
break;
/* If event is not already in the list */
if (&event_node->l == &counter->next_events_list) {
/* Allocate new event node */
event_node = kmalloc(sizeof(*event_node), GFP_KERNEL);
if (!event_node)
return -ENOMEM;
/* Configure event node and add to the list */
event_node->event = watch->event;
event_node->channel = watch->channel;
INIT_LIST_HEAD(&event_node->comp_list);
list_add(&event_node->l, &counter->next_events_list);
}
/* Check if component watch has already been set before */
list_for_each_entry(comp_node, &event_node->comp_list, l)
if (comp_node->parent == cfg->parent &&
counter_comp_read_is_equal(comp_node->comp, cfg->comp)) {
err = -EINVAL;
goto exit_free_event_node;
}
/* Allocate component node */
comp_node = kmalloc(sizeof(*comp_node), GFP_KERNEL);
if (!comp_node) {
err = -ENOMEM;
goto exit_free_event_node;
}
*comp_node = *cfg;
/* Add component node to event node */
list_add_tail(&comp_node->l, &event_node->comp_list);
exit_free_event_node:
/* Free event node if no one else is watching */
if (list_empty(&event_node->comp_list)) {
list_del(&event_node->l);
kfree(event_node);
}
return err;
}