[PATCH 1/2] [GPIOLib] GPIO Interrupt counter support v2

Greg KH greg at kroah.com
Wed May 28 07:35:30 PDT 2014


On Wed, May 28, 2014 at 12:17:48PM +0200, Federico Fuga wrote:
> This patch add a per-pin interrupt counter to GPIOs.
> This way, GPIOs Interrupt will increment an internal counter that
> can be accessed through sysfs. Counter can be read and written
> from user space.
> 
> Signed-off-by: Federico Fuga <fuga at studiofuga.com>
> ---
>  drivers/gpio/Kconfig       |  9 +++++
>  drivers/gpio/gpiolib.c     | 92 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/asm-generic/gpio.h | 25 +++++++++++++
>  3 files changed, 126 insertions(+)
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index b2450ba..cbdc62e 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -81,6 +81,15 @@ config GPIO_SYSFS
>  	  Kernel drivers may also request that a particular GPIO be
>  	  exported to userspace; this can be useful when debugging.
>  
> +config GPIO_COUNTER
> +	bool "GPIO Interrupt counter"
> +	help
> +	  Say Y here to add a per-pin interrupt counter to GPIOs.
> +
> +	  This way, GPIOs Interrupt will increment an internal counter that
> +	  can be accessed through sysfs. Counter can be read and written
> +	  from user space.
> +
>  config GPIO_GENERIC
>  	tristate
>  
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index ff0fd65..5829f7a 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -69,6 +69,10 @@ struct gpio_desc {
>  #ifdef CONFIG_DEBUG_FS
>  	const char		*label;
>  #endif
> +
> +#ifdef CONFIG_GPIO_COUNTER
> +	unsigned long    counter;    /* IRQ Events counter */
> +#endif
>  };
>  static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
>  
> @@ -583,9 +587,57 @@ static ssize_t gpio_active_low_store(struct device *dev,
>  static const DEVICE_ATTR(active_low, 0644,
>  		gpio_active_low_show, gpio_active_low_store);
>  
> +#ifdef CONFIG_GPIO_COUNTER
> +static ssize_t counter_store(struct device *dev,
> +		struct device_attribute *attr, const char *buf, size_t size)
> +{
> +	struct gpio_desc	*desc = dev_get_drvdata(dev);
> +	ssize_t			status;
> +
> +	mutex_lock(&sysfs_lock);
> +
> +	if (!test_bit(FLAG_EXPORT, &desc->flags)) {
> +		status = -EIO;
> +	} else {
> +		long		value;
> +
> +		status = kstrtol(buf, 10, &value);
> +		if (status == 0)
> +			desc->counter = value;
> +	}
> +
> +	mutex_unlock(&sysfs_lock);
> +
> +	return status ? : size;
> +
> +}
> +
> +static ssize_t counter_show(struct device *dev,
> +			       struct device_attribute *attr, char *buf)
> +{
> +	const struct gpio_desc	*desc = dev_get_drvdata(dev);
> +	ssize_t			status;
> +
> +	mutex_lock(&sysfs_lock);
> +
> +	if (!test_bit(FLAG_EXPORT, &desc->flags))
> +		status = -EIO;
> +	else
> +		status = sprintf(buf, "%ld\n", desc->counter);
> +
> +	mutex_unlock(&sysfs_lock);
> +
> +	return status;
> +}
> +static const DEVICE_ATTR_RW(counter);
> +#endif
> +
>  static const struct attribute *gpio_attrs[] = {
>  	&dev_attr_value.attr,
>  	&dev_attr_active_low.attr,
> +#ifdef CONFIG_GPIO_COUNTER
> +	&dev_attr_counter.attr,
> +#endif
>  	NULL,
>  };
>  
> @@ -1114,6 +1166,46 @@ static inline void gpiod_unexport(struct gpio_desc *desc)
>  
>  #endif /* CONFIG_GPIO_SYSFS */
>  
> +#ifdef CONFIG_GPIO_COUNTER
> +int gpio_counter_inc(unsigned gpio)
> +{
> +	struct gpio_desc	*desc = gpio_to_desc(gpio);
> +
> +	mutex_lock(&sysfs_lock);
> +	desc->counter++;
> +	mutex_unlock(&sysfs_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(gpio_counter_inc);
> +
> +long gpio_counter_get(unsigned gpio)
> +{
> +	long ret;
> +	struct gpio_desc	*desc = gpio_to_desc(gpio);
> +
> +	mutex_lock(&sysfs_lock);
> +	ret = desc->counter;
> +	mutex_unlock(&sysfs_lock);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(gpio_counter_get);
> +
> +int gpio_counter_set(unsigned gpio, long value)
> +{
> +	struct gpio_desc	*desc = gpio_to_desc(gpio);
> +
> +	mutex_lock(&sysfs_lock);
> +	desc->counter = value;
> +	mutex_unlock(&sysfs_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(gpio_counter_set);
> +#endif

Who uses these get/set functions?  If no one is using them, please don't
provide them, we don't add apis with no users in the kernel.  Or if you
do, someone else will come along and rip them out, which is wasteful of
time and developer resources...

thanks,

greg k-h



More information about the linux-rpi-kernel mailing list