On Wed, Oct 14, 2020 at 12:43:08PM -0500, David Lechner wrote: > On 9/26/20 9:18 PM, William Breathitt Gray wrote: > > diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c > > new file mode 100644 > > index 000000000000..2be3846e4105 > > --- /dev/null > > +++ b/drivers/counter/counter-chrdev.c > > > > +/** > > + * counter_push_event - queue event for userspace reading > > + * @counter: pointer to Counter structure > > + * @event: triggered event > > + * @channel: event channel > > + * > > + * Note: If no one is watching for the respective event, it is silently > > + * discarded. > > + * > > + * RETURNS: > > + * 0 on success, negative error number on failure. > > + */ > > +int counter_push_event(struct counter_device *const counter, const u8 event, > > + const u8 channel) > > +{ > > + struct counter_event ev = {0}; > > + unsigned int copied = 0; > > + unsigned long flags; > > + struct counter_event_node *event_node; > > + struct counter_comp_node *comp_node; > > + int err; > > + > > + ev.timestamp = ktime_get_ns(); > > + ev.watch.event = event; > > + ev.watch.channel = channel; > > + > > + raw_spin_lock_irqsave(&counter->events_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) { > > + err = counter_get_data(counter, comp_node, &ev.value_u8); > > Currently all counter devices are memory mapped devices so calling > counter_get_data() here with interrupts disabled is probably OK, but > if any counter drivers are added that use I2C/SPI/etc. that will take > a long time to read, it would cause problems leaving interrupts > disabled here. > > Brainstorming: Would it make sense to separate the event from the > component value being read? As I mentioned in one of my previous > reviews, I think there are some cases where we would just want to > know when an event happened and not read any additional data anyway. > In the case of a slow communication bus, this would also let us > queue the event in the kfifo and notify poll right away and then > defer the reads in a workqueue for later. I don't see any problems with reporting just an event without any component value attached (e.g. userspace could handle the component reads via sysfs at a later point). We would just need a way to inform userspace that the struct counter_component in the struct counter_watch returned should be ignored. Perhaps we can add an additional member to struct counter_watch indicating whether it's an empty watch; or alternatively, add a new component scope define to differentiate between an actual component and an empty one (e.g. COUNTER_SCOPE_EVENT). What do you think? William Breathitt Gray