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.szyprow...@samsung.com> > Signed-off-by: Charles Keepax <ckee...@opensource.cirrus.com> Tested-by: Marek Szyprowski <m.szyprow...@samsung.com> > --- > 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