Re: [PATCH 3/3] gpio: Add reference counting for non-exclusive GPIOs
From: Marek Szyprowski
Date: Fri Nov 23 2018 - 04:25:15 EST
Hi Charles,
On 2018-11-22 18:30, Charles Keepax wrote:
> Currently, a GPIO can be requested multiple times when the
> NONEXCLUSIVE flag is set, however it must still be freed a single
> time. This makes client code rather complex, since multiple drivers
> may request the GPIO but only a single one can free it. Rather than
> manually handling this in each driver add some basic reference
> counting into the core. Currently, this is fairly primitive but
> so is the support for the NONEXCLUSIVE flag and the implementation
> covers those use-cases.
>
> Reported-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
> Signed-off-by: Charles Keepax <ckeepax@xxxxxxxxxxxxxxxxxxxxx>
Tested-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
> ---
> drivers/gpio/gpiolib.c | 13 ++++++++++++-
> drivers/gpio/gpiolib.h | 2 ++
> 2 files changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index 230e41562462b..42ba86fb495a5 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -2407,6 +2407,13 @@ static bool gpiod_free_commit(struct gpio_desc *desc)
>
> might_sleep();
>
> + if (desc->n_users > 1) {
> + desc->n_users--;
> + return true;
> + } else {
> + desc->n_users = 0;
> + }
> +
> gpiod_unexport(desc);
>
> spin_lock_irqsave(&gpio_lock, flags);
> @@ -4142,7 +4149,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
> */
> dev_info(dev, "nonexclusive access to GPIO for %s\n",
> con_id ? con_id : devname);
> - return desc;
> +
> + goto done;
> } else {
> return ERR_PTR(status);
> }
> @@ -4155,6 +4163,9 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
> return ERR_PTR(status);
> }
>
> +done:
> + desc->n_users++;
> +
> return desc;
> }
> EXPORT_SYMBOL_GPL(gpiod_get_index);
> diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
> index 087d865286a0c..f96eda90281a3 100644
> --- a/drivers/gpio/gpiolib.h
> +++ b/drivers/gpio/gpiolib.h
> @@ -230,6 +230,8 @@ struct gpio_desc {
> const char *label;
> /* Name of the GPIO */
> const char *name;
> +
> + unsigned int n_users;
> };
>
> int gpiod_request(struct gpio_desc *desc, const char *label);
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland