Hi-- On 4/6/20 8:58 AM, Kamel Bouhara wrote: > --- > drivers/counter/counter.c | 213 ++++++++++++++++++++++++++++++++++++++ > include/linux/counter.h | 27 +++++ > 2 files changed, 240 insertions(+) > > diff --git a/drivers/counter/counter.c b/drivers/counter/counter.c > index 6a683d086008..f81d2d1dbca7 100644 > --- a/drivers/counter/counter.c > +++ b/drivers/counter/counter.c [snip] Please use /** on these functions so that kernel-doc will process them. > + > +/* > + * devm_counter_get - Obtain an exclusive access to a counter. > + * @dev: device for counter "consumer" > + * > + * Returns a struct counter_device matching the counter producer, or > + * IS_ERR() condition containing errno. > + * > + */ > +struct counter_device *devm_counter_get(struct device *dev) > +{ > + struct counter_device **ptr, *counter; > + > + ptr = devres_alloc(devm_counter_release, sizeof(*ptr), GFP_KERNEL); > + if (!ptr) > + return ERR_PTR(-ENOMEM); > + > + counter = counter_get(dev); > + if (IS_ERR(counter)) { > + devres_free(ptr); > + return counter; > + } > + > + *ptr = counter; > + devres_add(dev, ptr); > + > + return counter; > +} > +EXPORT_SYMBOL_GPL(devm_counter_get); > + > +/* > + * counter_action_get - get counter synapse mode > + * @counter: counter device to operate with > + * @action: pointer to store the current counter synapse mode should be @mode: ^^^^^ > + * returns: > + * 0 on success, error code on failure. > + */ > +int counter_action_get(struct counter_device *counter, int *mode) > +{ > + struct counter_synapse *synapse = counter->counts->synapses; > + size_t action_index; > + int err; > + > + err = counter->ops->action_get(counter, counter->counts, synapse, > + &action_index); > + if (err) > + return err; > + > + *mode = synapse->actions_list[action_index]; > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(counter_action_get); > + > +/* > + * counter_action_set - set counter device synapse > + * @counter: counter device to operate with > + * @action: enum of the synapse mode > + * returns: > + * 0 on success, error code on failure. > + */ > +int counter_action_set(struct counter_device *counter, > + enum counter_synapse_action action) > +{ > + struct counter_synapse *synapse = counter->counts->synapses; > + const size_t num_actions = synapse->num_actions; > + size_t action_index; > + > + /* Find requested action mode */ > + for (action_index = 0; action_index < num_actions; action_index++) { > + if (action == synapse->actions_list[action_index]) > + break; > + } > + > + if (action_index >= num_actions) > + return -EINVAL; > + > + return counter->ops->action_set(counter, counter->counts, synapse, > + action_index); > +} > +EXPORT_SYMBOL_GPL(counter_action_set); > + > +/* > + * counter_function_get - get the count function > + * @counter: pointer to counter device to operate with > + * @mode: pointer to store the current counter function mode > + * returns: > + * 0 on success, error code on failure. > + */ > +int counter_function_get(struct counter_device *counter, int *mode) > +{ > + size_t func_index; > + int err; > + > + err = counter->ops->function_get(counter, counter->counts, > + &func_index); > + if (err) > + return err; > + > + *mode = counter->counts->functions_list[func_index]; > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(counter_function_get); > + > +/* > + * counter_function_set - set a count function > + * @counter: pointer to a counter device to operate with > + * @function: enum of the function mode > + * returns: > + * 0 on success, error code on failure. > + */ > +int counter_function_set(struct counter_device *counter, > + enum counter_count_function function) > +{ > + const size_t num_functions = counter->counts->num_functions; > + size_t func_index; > + > + for (func_index = 0; func_index < num_functions; func_index++) { > + if (function == counter->counts->functions_list[func_index]) > + break; > + } > + > + if (func_index >= num_functions) > + return -EINVAL; > + > + return counter->ops->function_set(counter, counter->counts, func_index); > +} > +EXPORT_SYMBOL_GPL(counter_function_set); > + > +/* > + * counter_count_set - set a count value > + * @counter: pointer to the counter device to operate with > + * @val: count value to write into the counter > + * @len: length of the value written to the counter > + * returns: > + * bytes length of the value on success, error code on failure. > + */ > +size_t counter_count_set(struct counter_device *counter, > + unsigned long val, size_t len) > +{ > + return counter->ops->count_write(counter, counter->counts, val); > +} > +EXPORT_SYMBOL_GPL(counter_count_set); > + > +/* > + * counter_count_get - read the count value > + * @counter: pointer to the counter device to operate with > + * @val: pointer to store the count value > + * returns: > + * 0 on success, error code on failure. > + */ > +int counter_count_get(struct counter_device *counter, unsigned long *val) > +{ > + return counter->ops->count_read(counter, counter->counts, val); > +} > +EXPORT_SYMBOL_GPL(counter_count_get); > + > /** > * devm_counter_unregister - Resource-managed counter_unregister > * @dev: device this counter_device belongs to thanks. -- ~Randy