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

Greg KH greg at kroah.com
Tue May 27 12:12:54 PDT 2014


On Tue, May 27, 2014 at 08:47:28PM +0200, Federico Fuga wrote:
> Interrupt counter support inside GPIOLib

What is this for?  What will it provide me?

> 
> Signed-off-by: Federico Fuga <fuga at studiofuga.com>
> ---
>  drivers/gpio/Kconfig       |  3 ++
>  drivers/gpio/gpiolib.c     | 90 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/asm-generic/gpio.h |  6 ++++
>  3 files changed, 99 insertions(+)
> 
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index b2450ba..d371e3c 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -81,6 +81,9 @@ 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 (where available)"

No help text?  What is this?  What is it good for?  Why would I want to
enable it?

> +
>  config GPIO_GENERIC
>  	tristate
>  
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index ff0fd65..c052cba 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,55 @@ 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);
>  
> +
> +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 = strict_strtol(buf, 0, &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 DEVICE_ATTR(counter, 0666, counter_show, counter_store);

DEVICE_ATTR_RW()?



> +
> +
>  static const struct attribute *gpio_attrs[] = {
>  	&dev_attr_value.attr,
>  	&dev_attr_active_low.attr,
> +	&dev_attr_counter.attr,
>  	NULL,
>  };
>  
> @@ -1114,6 +1164,46 @@ static inline void gpiod_unexport(struct gpio_desc *desc)
>  
>  #endif /* CONFIG_GPIO_SYSFS */
>  
> +#ifdef CONFIG_GPIO_COUNTER
> +int gpio_counter_inc (unsigned gpio) 

Trailing whitespace :(

> +{
> +	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
> +
> +
>  /*
>   * Add a new chip to the global chips list, keeping the list of chips sorted
>   * by base order.
> diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
> index bde6469..2d40187 100644
> --- a/include/asm-generic/gpio.h
> +++ b/include/asm-generic/gpio.h
> @@ -210,6 +210,12 @@ extern void gpio_unexport(unsigned gpio);
>  
>  #endif	/* CONFIG_GPIO_SYSFS */
>  
> +#ifdef CONFIG_GPIO_COUNTER
> +extern int gpio_counter_inc (unsigned gpio);
> +extern long gpio_counter_get (unsigned gpio);
> +extern int gpio_counter_set (unsigned gpio, long value);
> +#endif

Provide versions here that are "empty" if the option is not enabled.

thanks,

greg k-h



More information about the linux-rpi-kernel mailing list