diff mbox

[1/6] gpiolib: Allow GPIO chips to request their own GPIOs

Message ID 1393257611-18031-2-git-send-email-mika.westerberg@linux.intel.com (mailing list archive)
State Changes Requested, archived
Headers show

Commit Message

Mika Westerberg Feb. 24, 2014, 4 p.m. UTC
Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
own through gpiolib API. One usecase is ACPI ASL code that should be able
to toggle GPIOs through GPIO operation regions.

We can't really use gpio_request() and its counterparts because it will pin
the module to the kernel forever (as it calls module_get()). Instead we
provide a gpiolib internal functions gpiochip_request/free_own_desc() that
work the same as gpio_request() but don't manipulate module refrence count.

Since it's the GPIO chip driver who requests the GPIOs in the first place
we can be sure that it cannot be unloaded without the driver knowing about
that. Furthermore we only limit this functionality to be available only
inside gpiolib.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/gpio/gpiolib.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------
 drivers/gpio/gpiolib.h |  3 +++
 2 files changed, 53 insertions(+), 7 deletions(-)

Comments

Rafael J. Wysocki Feb. 25, 2014, 2:10 p.m. UTC | #1
On Monday, February 24, 2014 06:00:06 PM Mika Westerberg wrote:
> Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
> own through gpiolib API. One usecase is ACPI ASL code that should be able
> to toggle GPIOs through GPIO operation regions.
> 
> We can't really use gpio_request() and its counterparts because it will pin
> the module to the kernel forever (as it calls module_get()). Instead we
> provide a gpiolib internal functions gpiochip_request/free_own_desc() that
> work the same as gpio_request() but don't manipulate module refrence count.
> 
> Since it's the GPIO chip driver who requests the GPIOs in the first place
> we can be sure that it cannot be unloaded without the driver knowing about
> that. Furthermore we only limit this functionality to be available only
> inside gpiolib.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/gpio/gpiolib.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------
>  drivers/gpio/gpiolib.h |  3 +++
>  2 files changed, 53 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index f60d74bc2fce..489a63524eb6 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -1458,7 +1458,8 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
>   * on each other, and help provide better diagnostics in debugfs.
>   * They're called even less than the "set direction" calls.
>   */
> -static int gpiod_request(struct gpio_desc *desc, const char *label)
> +static int __gpiod_request(struct gpio_desc *desc, const char *label,
> +			   bool module_refcount)
>  {
>  	struct gpio_chip	*chip;
>  	int			status = -EPROBE_DEFER;
> @@ -1475,8 +1476,10 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
>  	if (chip == NULL)
>  		goto done;
>  
> -	if (!try_module_get(chip->owner))
> -		goto done;
> +	if (module_refcount) {
> +		if (!try_module_get(chip->owner))
> +			goto done;
> +	}

I'm wondering why you're not moving the module refcount manipulation entirely
to gpiod_request()?

I guess that's because of the locking, but I suppose that desc->chip will never
be NULL in gpiochip_request_own_desc(), so you don't even need to check it there?

So it looks like gpiochip_request_own_desc() can do something like

	lock
	__gpiod_request(stuff)
	unlock

where __gpiod_request() is just the internal part starting at the "NOTE" comment.

>  
>  	/* NOTE:  gpio_request() can be called in early boot,
>  	 * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
> @@ -1487,7 +1490,8 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
>  		status = 0;
>  	} else {
>  		status = -EBUSY;
> -		module_put(chip->owner);
> +		if (module_refcount)
> +			module_put(chip->owner);
>  		goto done;
>  	}
>  
> @@ -1499,7 +1503,8 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
>  
>  		if (status < 0) {
>  			desc_set_label(desc, NULL);
> -			module_put(chip->owner);
> +			if (module_refcount)
> +				module_put(chip->owner);
>  			clear_bit(FLAG_REQUESTED, &desc->flags);
>  			goto done;
>  		}
> @@ -1517,13 +1522,18 @@ done:
>  	return status;
>  }
>  
> +static int gpiod_request(struct gpio_desc *desc, const char *label)
> +{
> +	return __gpiod_request(desc, label, true);
> +}
> +
>  int gpio_request(unsigned gpio, const char *label)
>  {
>  	return gpiod_request(gpio_to_desc(gpio), label);
>  }
>  EXPORT_SYMBOL_GPL(gpio_request);
>  
> -static void gpiod_free(struct gpio_desc *desc)
> +static void __gpiod_free(struct gpio_desc *desc, bool module_refcount)
>  {
>  	unsigned long		flags;
>  	struct gpio_chip	*chip;
> @@ -1548,7 +1558,8 @@ static void gpiod_free(struct gpio_desc *desc)
>  			spin_lock_irqsave(&gpio_lock, flags);
>  		}
>  		desc_set_label(desc, NULL);
> -		module_put(desc->chip->owner);
> +		if (module_refcount)
> +			module_put(desc->chip->owner);
>  		clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
>  		clear_bit(FLAG_REQUESTED, &desc->flags);
>  		clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
> @@ -1559,6 +1570,11 @@ static void gpiod_free(struct gpio_desc *desc)
>  	spin_unlock_irqrestore(&gpio_lock, flags);
>  }
>  
> +static void gpiod_free(struct gpio_desc *desc)
> +{
> +	__gpiod_free(desc, true);
> +}
> +
>  void gpio_free(unsigned gpio)
>  {
>  	gpiod_free(gpio_to_desc(gpio));
> @@ -1678,6 +1694,33 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
>  }
>  EXPORT_SYMBOL_GPL(gpiochip_is_requested);
>  
> +/**
> + * gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor
> + * @desc: GPIO descriptor to request
> + * @label: label for the GPIO
> + *
> + * Function allows GPIO chip drivers to request and use their own GPIO
> + * descriptors via gpiolib API. Difference to gpiod_request() is that this
> + * function will not increase reference count of the GPIO chip module. This
> + * allows the GPIO chip module to be unloaded as needed (we assume that the
> + * GPIO chip driver handles freeing the GPIOs it has requested).
> + */
> +int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label)
> +{
> +	return __gpiod_request(desc, label, false);
> +}
> +
> +/**
> + * gpiochip_free_own_desc - Free GPIO requested by the chip driver
> + * @desc: GPIO descriptor to free
> + *
> + * Function frees the given GPIO requested previously with
> + * gpiochip_request_own_desc().
> + */
> +void gpiochip_free_own_desc(struct gpio_desc *desc)
> +{
> +	__gpiod_free(desc, false);
> +}
>  
>  /* Drivers MUST set GPIO direction before making get/set calls.  In
>   * some cases this is done in early boot, before IRQs are enabled.
> diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
> index 82be586c1f90..cf092941a9fd 100644
> --- a/drivers/gpio/gpiolib.h
> +++ b/drivers/gpio/gpiolib.h
> @@ -43,4 +43,7 @@ acpi_get_gpiod_by_index(struct device *dev, int index,
>  }
>  #endif
>  
> +int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label);
> +void gpiochip_free_own_desc(struct gpio_desc *desc);
> +
>  #endif /* GPIOLIB_H */
>
Mika Westerberg Feb. 26, 2014, 9:05 a.m. UTC | #2
On Tue, Feb 25, 2014 at 03:10:24PM +0100, Rafael J. Wysocki wrote:
> On Monday, February 24, 2014 06:00:06 PM Mika Westerberg wrote:
> > Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
> > own through gpiolib API. One usecase is ACPI ASL code that should be able
> > to toggle GPIOs through GPIO operation regions.
> > 
> > We can't really use gpio_request() and its counterparts because it will pin
> > the module to the kernel forever (as it calls module_get()). Instead we
> > provide a gpiolib internal functions gpiochip_request/free_own_desc() that
> > work the same as gpio_request() but don't manipulate module refrence count.
> > 
> > Since it's the GPIO chip driver who requests the GPIOs in the first place
> > we can be sure that it cannot be unloaded without the driver knowing about
> > that. Furthermore we only limit this functionality to be available only
> > inside gpiolib.
> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > ---
> >  drivers/gpio/gpiolib.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------
> >  drivers/gpio/gpiolib.h |  3 +++
> >  2 files changed, 53 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> > index f60d74bc2fce..489a63524eb6 100644
> > --- a/drivers/gpio/gpiolib.c
> > +++ b/drivers/gpio/gpiolib.c
> > @@ -1458,7 +1458,8 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
> >   * on each other, and help provide better diagnostics in debugfs.
> >   * They're called even less than the "set direction" calls.
> >   */
> > -static int gpiod_request(struct gpio_desc *desc, const char *label)
> > +static int __gpiod_request(struct gpio_desc *desc, const char *label,
> > +			   bool module_refcount)
> >  {
> >  	struct gpio_chip	*chip;
> >  	int			status = -EPROBE_DEFER;
> > @@ -1475,8 +1476,10 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
> >  	if (chip == NULL)
> >  		goto done;
> >  
> > -	if (!try_module_get(chip->owner))
> > -		goto done;
> > +	if (module_refcount) {
> > +		if (!try_module_get(chip->owner))
> > +			goto done;
> > +	}
> 
> I'm wondering why you're not moving the module refcount manipulation entirely
> to gpiod_request()?
> 
> I guess that's because of the locking, but I suppose that desc->chip will never
> be NULL in gpiochip_request_own_desc(), so you don't even need to check it there?
> 
> So it looks like gpiochip_request_own_desc() can do something like
> 
> 	lock
> 	__gpiod_request(stuff)
> 	unlock
> 
> where __gpiod_request() is just the internal part starting at the "NOTE" comment.

Sounds good. Only thing I'm not sure about is the fact that
__gpiod_request() releases the lock when it calls chip driver callbacks
(and takes it back of course). Is that acceptable practice to take the lock
outside of a function and release it inside for a while?
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael J. Wysocki Feb. 26, 2014, 1:47 p.m. UTC | #3
On Wednesday, February 26, 2014 11:05:42 AM Mika Westerberg wrote:
> On Tue, Feb 25, 2014 at 03:10:24PM +0100, Rafael J. Wysocki wrote:
> > On Monday, February 24, 2014 06:00:06 PM Mika Westerberg wrote:
> > > Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
> > > own through gpiolib API. One usecase is ACPI ASL code that should be able
> > > to toggle GPIOs through GPIO operation regions.
> > > 
> > > We can't really use gpio_request() and its counterparts because it will pin
> > > the module to the kernel forever (as it calls module_get()). Instead we
> > > provide a gpiolib internal functions gpiochip_request/free_own_desc() that
> > > work the same as gpio_request() but don't manipulate module refrence count.
> > > 
> > > Since it's the GPIO chip driver who requests the GPIOs in the first place
> > > we can be sure that it cannot be unloaded without the driver knowing about
> > > that. Furthermore we only limit this functionality to be available only
> > > inside gpiolib.
> > > 
> > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > ---
> > >  drivers/gpio/gpiolib.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------
> > >  drivers/gpio/gpiolib.h |  3 +++
> > >  2 files changed, 53 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> > > index f60d74bc2fce..489a63524eb6 100644
> > > --- a/drivers/gpio/gpiolib.c
> > > +++ b/drivers/gpio/gpiolib.c
> > > @@ -1458,7 +1458,8 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
> > >   * on each other, and help provide better diagnostics in debugfs.
> > >   * They're called even less than the "set direction" calls.
> > >   */
> > > -static int gpiod_request(struct gpio_desc *desc, const char *label)
> > > +static int __gpiod_request(struct gpio_desc *desc, const char *label,
> > > +			   bool module_refcount)
> > >  {
> > >  	struct gpio_chip	*chip;
> > >  	int			status = -EPROBE_DEFER;
> > > @@ -1475,8 +1476,10 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
> > >  	if (chip == NULL)
> > >  		goto done;
> > >  
> > > -	if (!try_module_get(chip->owner))
> > > -		goto done;
> > > +	if (module_refcount) {
> > > +		if (!try_module_get(chip->owner))
> > > +			goto done;
> > > +	}
> > 
> > I'm wondering why you're not moving the module refcount manipulation entirely
> > to gpiod_request()?
> > 
> > I guess that's because of the locking, but I suppose that desc->chip will never
> > be NULL in gpiochip_request_own_desc(), so you don't even need to check it there?
> > 
> > So it looks like gpiochip_request_own_desc() can do something like
> > 
> > 	lock
> > 	__gpiod_request(stuff)
> > 	unlock
> > 
> > where __gpiod_request() is just the internal part starting at the "NOTE" comment.
> 
> Sounds good. Only thing I'm not sure about is the fact that
> __gpiod_request() releases the lock when it calls chip driver callbacks
> (and takes it back of course). Is that acceptable practice to take the lock
> outside of a function and release it inside for a while?

Yes, you can do that.

There even are sparse annotations for that: __releases() and __acquires()
(__rpm_callback() in drivers/base/power/runtime.c uses them among other things).
Mika Westerberg Feb. 27, 2014, 9:48 a.m. UTC | #4
On Wed, Feb 26, 2014 at 02:47:58PM +0100, Rafael J. Wysocki wrote:
> > Sounds good. Only thing I'm not sure about is the fact that
> > __gpiod_request() releases the lock when it calls chip driver callbacks
> > (and takes it back of course). Is that acceptable practice to take the lock
> > outside of a function and release it inside for a while?
> 
> Yes, you can do that.
> 
> There even are sparse annotations for that: __releases() and __acquires()
> (__rpm_callback() in drivers/base/power/runtime.c uses them among other things).

Ah, good to know. Thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Walleij March 5, 2014, 2:49 a.m. UTC | #5
On Tue, Feb 25, 2014 at 12:00 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
> own through gpiolib API. One usecase is ACPI ASL code that should be able
> to toggle GPIOs through GPIO operation regions.
>
> We can't really use gpio_request() and its counterparts because it will pin
> the module to the kernel forever (as it calls module_get()). Instead we
> provide a gpiolib internal functions gpiochip_request/free_own_desc() that
> work the same as gpio_request() but don't manipulate module refrence count.
>
> Since it's the GPIO chip driver who requests the GPIOs in the first place
> we can be sure that it cannot be unloaded without the driver knowing about
> that. Furthermore we only limit this functionality to be available only
> inside gpiolib.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

I fully trust you in doing the ACPI stuff in patches 2-n but on this patch
in particular I want Alexandre's review tag as well, as he's working
actively with the descriptor API and I don't want to add too many quirks
without his consent.

So Alexandre, what do you say about this?

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mika Westerberg March 5, 2014, 12:05 p.m. UTC | #6
On Wed, Mar 05, 2014 at 10:49:41AM +0800, Linus Walleij wrote:
> On Tue, Feb 25, 2014 at 12:00 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> 
> > Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
> > own through gpiolib API. One usecase is ACPI ASL code that should be able
> > to toggle GPIOs through GPIO operation regions.
> >
> > We can't really use gpio_request() and its counterparts because it will pin
> > the module to the kernel forever (as it calls module_get()). Instead we
> > provide a gpiolib internal functions gpiochip_request/free_own_desc() that
> > work the same as gpio_request() but don't manipulate module refrence count.
> >
> > Since it's the GPIO chip driver who requests the GPIOs in the first place
> > we can be sure that it cannot be unloaded without the driver knowing about
> > that. Furthermore we only limit this functionality to be available only
> > inside gpiolib.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> I fully trust you in doing the ACPI stuff in patches 2-n but on this patch
> in particular I want Alexandre's review tag as well, as he's working
> actively with the descriptor API and I don't want to add too many quirks
> without his consent.

Thanks for your trust :)

> So Alexandre, what do you say about this?

I'm about to send v2 of the series with Rafael's comments taken into
account. However, I stumbled to another locking problem:

I'm going to move taking the gpio_lock outside of __gpiod_request() and
have __gpiod_request() to release that lock, so that we can call
chip->request() safely.

Since we are using _irqsave()/_irqrestore() versions, it means that I need
to pass flags as a pointer from gpiod_request() to __gpiod_request() like:

	spin_lock_irqsave(&gpio_lock, flags);
	if (try_module_get(chip->owner)) {
		ret = __gpiod_request(desc, label, &flags);
		...

Is that acceptable or can you guys suggest some alternative? One
alternative that I can think about is to have __gpiod_request() to take the
lock and move try_module_get() outside to gpiod_request():

__gpiod_request()
{
	unsigned long flags;

	spin_lock_irqsave(&gpio_lock, flags);
	...
}

gpiod_request():
{
	...
	if (try_module_get(chip->owner)) {
		ret = __gpiod_request(desc, label);
		...
}

Thoughts?
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael J. Wysocki March 5, 2014, 1:07 p.m. UTC | #7
On Wednesday, March 05, 2014 02:05:50 PM Mika Westerberg wrote:
> On Wed, Mar 05, 2014 at 10:49:41AM +0800, Linus Walleij wrote:
> > On Tue, Feb 25, 2014 at 12:00 AM, Mika Westerberg
> > <mika.westerberg@linux.intel.com> wrote:
> > 
> > > Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
> > > own through gpiolib API. One usecase is ACPI ASL code that should be able
> > > to toggle GPIOs through GPIO operation regions.
> > >
> > > We can't really use gpio_request() and its counterparts because it will pin
> > > the module to the kernel forever (as it calls module_get()). Instead we
> > > provide a gpiolib internal functions gpiochip_request/free_own_desc() that
> > > work the same as gpio_request() but don't manipulate module refrence count.
> > >
> > > Since it's the GPIO chip driver who requests the GPIOs in the first place
> > > we can be sure that it cannot be unloaded without the driver knowing about
> > > that. Furthermore we only limit this functionality to be available only
> > > inside gpiolib.
> > >
> > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > 
> > I fully trust you in doing the ACPI stuff in patches 2-n but on this patch
> > in particular I want Alexandre's review tag as well, as he's working
> > actively with the descriptor API and I don't want to add too many quirks
> > without his consent.
> 
> Thanks for your trust :)
> 
> > So Alexandre, what do you say about this?
> 
> I'm about to send v2 of the series with Rafael's comments taken into
> account. However, I stumbled to another locking problem:
> 
> I'm going to move taking the gpio_lock outside of __gpiod_request() and
> have __gpiod_request() to release that lock, so that we can call
> chip->request() safely.
> 
> Since we are using _irqsave()/_irqrestore() versions, it means that I need
> to pass flags as a pointer from gpiod_request() to __gpiod_request() like:
> 
> 	spin_lock_irqsave(&gpio_lock, flags);
> 	if (try_module_get(chip->owner)) {
> 		ret = __gpiod_request(desc, label, &flags);

Ouch.  Sorry for overlooking that.

> 		...
> 
> Is that acceptable or can you guys suggest some alternative? One
> alternative that I can think about is to have __gpiod_request() to take the
> lock and move try_module_get() outside to gpiod_request():
> 
> __gpiod_request()
> {
> 	unsigned long flags;
> 
> 	spin_lock_irqsave(&gpio_lock, flags);
> 	...
> }
> 
> gpiod_request():
> {
> 	...
> 	if (try_module_get(chip->owner)) {
> 		ret = __gpiod_request(desc, label);
> 		...
> }
> 
> Thoughts?

If that works, it would be better than passing the flags IMO.
Alexandre Courbot March 6, 2014, 2:16 a.m. UTC | #8
On Wed, Mar 5, 2014 at 11:49 AM, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Tue, Feb 25, 2014 at 12:00 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
>
>> Sometimes it is useful to allow GPIO chips themselves to request GPIOs they
>> own through gpiolib API. One usecase is ACPI ASL code that should be able
>> to toggle GPIOs through GPIO operation regions.
>>
>> We can't really use gpio_request() and its counterparts because it will pin
>> the module to the kernel forever (as it calls module_get()). Instead we
>> provide a gpiolib internal functions gpiochip_request/free_own_desc() that
>> work the same as gpio_request() but don't manipulate module refrence count.
>>
>> Since it's the GPIO chip driver who requests the GPIOs in the first place
>> we can be sure that it cannot be unloaded without the driver knowing about
>> that. Furthermore we only limit this functionality to be available only
>> inside gpiolib.
>>
>> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
>
> I fully trust you in doing the ACPI stuff in patches 2-n but on this patch
> in particular I want Alexandre's review tag as well, as he's working
> actively with the descriptor API and I don't want to add too many quirks
> without his consent.
>
> So Alexandre, what do you say about this?

I will wait for v2 to give it a real review, but since the new
functions are not exposed outside of gpiolib and the patch seems to
serve a real purpose I have no objection to it. Especially if Rafael's
suggestions can be applied.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f60d74bc2fce..489a63524eb6 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1458,7 +1458,8 @@  EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
  * on each other, and help provide better diagnostics in debugfs.
  * They're called even less than the "set direction" calls.
  */
-static int gpiod_request(struct gpio_desc *desc, const char *label)
+static int __gpiod_request(struct gpio_desc *desc, const char *label,
+			   bool module_refcount)
 {
 	struct gpio_chip	*chip;
 	int			status = -EPROBE_DEFER;
@@ -1475,8 +1476,10 @@  static int gpiod_request(struct gpio_desc *desc, const char *label)
 	if (chip == NULL)
 		goto done;
 
-	if (!try_module_get(chip->owner))
-		goto done;
+	if (module_refcount) {
+		if (!try_module_get(chip->owner))
+			goto done;
+	}
 
 	/* NOTE:  gpio_request() can be called in early boot,
 	 * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
@@ -1487,7 +1490,8 @@  static int gpiod_request(struct gpio_desc *desc, const char *label)
 		status = 0;
 	} else {
 		status = -EBUSY;
-		module_put(chip->owner);
+		if (module_refcount)
+			module_put(chip->owner);
 		goto done;
 	}
 
@@ -1499,7 +1503,8 @@  static int gpiod_request(struct gpio_desc *desc, const char *label)
 
 		if (status < 0) {
 			desc_set_label(desc, NULL);
-			module_put(chip->owner);
+			if (module_refcount)
+				module_put(chip->owner);
 			clear_bit(FLAG_REQUESTED, &desc->flags);
 			goto done;
 		}
@@ -1517,13 +1522,18 @@  done:
 	return status;
 }
 
+static int gpiod_request(struct gpio_desc *desc, const char *label)
+{
+	return __gpiod_request(desc, label, true);
+}
+
 int gpio_request(unsigned gpio, const char *label)
 {
 	return gpiod_request(gpio_to_desc(gpio), label);
 }
 EXPORT_SYMBOL_GPL(gpio_request);
 
-static void gpiod_free(struct gpio_desc *desc)
+static void __gpiod_free(struct gpio_desc *desc, bool module_refcount)
 {
 	unsigned long		flags;
 	struct gpio_chip	*chip;
@@ -1548,7 +1558,8 @@  static void gpiod_free(struct gpio_desc *desc)
 			spin_lock_irqsave(&gpio_lock, flags);
 		}
 		desc_set_label(desc, NULL);
-		module_put(desc->chip->owner);
+		if (module_refcount)
+			module_put(desc->chip->owner);
 		clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
 		clear_bit(FLAG_REQUESTED, &desc->flags);
 		clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
@@ -1559,6 +1570,11 @@  static void gpiod_free(struct gpio_desc *desc)
 	spin_unlock_irqrestore(&gpio_lock, flags);
 }
 
+static void gpiod_free(struct gpio_desc *desc)
+{
+	__gpiod_free(desc, true);
+}
+
 void gpio_free(unsigned gpio)
 {
 	gpiod_free(gpio_to_desc(gpio));
@@ -1678,6 +1694,33 @@  const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
 }
 EXPORT_SYMBOL_GPL(gpiochip_is_requested);
 
+/**
+ * gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor
+ * @desc: GPIO descriptor to request
+ * @label: label for the GPIO
+ *
+ * Function allows GPIO chip drivers to request and use their own GPIO
+ * descriptors via gpiolib API. Difference to gpiod_request() is that this
+ * function will not increase reference count of the GPIO chip module. This
+ * allows the GPIO chip module to be unloaded as needed (we assume that the
+ * GPIO chip driver handles freeing the GPIOs it has requested).
+ */
+int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label)
+{
+	return __gpiod_request(desc, label, false);
+}
+
+/**
+ * gpiochip_free_own_desc - Free GPIO requested by the chip driver
+ * @desc: GPIO descriptor to free
+ *
+ * Function frees the given GPIO requested previously with
+ * gpiochip_request_own_desc().
+ */
+void gpiochip_free_own_desc(struct gpio_desc *desc)
+{
+	__gpiod_free(desc, false);
+}
 
 /* Drivers MUST set GPIO direction before making get/set calls.  In
  * some cases this is done in early boot, before IRQs are enabled.
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 82be586c1f90..cf092941a9fd 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -43,4 +43,7 @@  acpi_get_gpiod_by_index(struct device *dev, int index,
 }
 #endif
 
+int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label);
+void gpiochip_free_own_desc(struct gpio_desc *desc);
+
 #endif /* GPIOLIB_H */