diff mbox series

[v5,3/6] gpiolib: acpi: Export acpi_get_gpiod()

Message ID 20210603224007.120560-4-djrscally@gmail.com
State New
Headers show
Series Introduce intel_skl_int3472 module | expand

Commit Message

Daniel Scally June 3, 2021, 10:40 p.m. UTC
We need to be able to translate GPIO resources in an ACPI device's _CRS
into GPIO descriptor array. Those are represented in _CRS as a pathname
to a GPIO device plus the pin's index number: the acpi_get_gpiod()
function is perfect for that purpose.

As it's currently only used internally within the GPIO layer, provide and
export a wrapper function that additionally holds a reference to the GPIO
device.

Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
---
Changes since v4:
	- None

 drivers/gpio/gpiolib-acpi.c   | 28 ++++++++++++++++++++++++++++
 include/linux/gpio/consumer.h |  2 ++
 2 files changed, 30 insertions(+)

Comments

Andy Shevchenko June 4, 2021, 12:59 p.m. UTC | #1
On Thu, Jun 03, 2021 at 11:40:04PM +0100, Daniel Scally wrote:
> We need to be able to translate GPIO resources in an ACPI device's _CRS

> into GPIO descriptor array. Those are represented in _CRS as a pathname

> to a GPIO device plus the pin's index number: the acpi_get_gpiod()

> function is perfect for that purpose.

> 

> As it's currently only used internally within the GPIO layer, provide and

> export a wrapper function that additionally holds a reference to the GPIO

> device.


The subject is wrong, it should be "Introduce acpi_get_and_request_gpiod()
helper" or so. I can fix when applying.

Btw, do I understand correctly that I may push GPIO ACPI patches independently
(of the ACPI changes)?

> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> Signed-off-by: Daniel Scally <djrscally@gmail.com>

> ---

> Changes since v4:

> 	- None

> 

>  drivers/gpio/gpiolib-acpi.c   | 28 ++++++++++++++++++++++++++++

>  include/linux/gpio/consumer.h |  2 ++

>  2 files changed, 30 insertions(+)

> 

> diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c

> index 5b4111e4be3f..684ddb35d83b 100644

> --- a/drivers/gpio/gpiolib-acpi.c

> +++ b/drivers/gpio/gpiolib-acpi.c

> @@ -128,6 +128,34 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)

>  	return gpiochip_get_desc(chip, pin);

>  }

>  

> +/**

> + * acpi_get_and_request_gpiod() - Translate ACPI GPIO pin to GPIO descriptor

> + *                               and hold a refcount to the GPIO device.

> + * @path:      ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")

> + * @pin:       ACPI GPIO pin number (0-based, controller-relative)

> + * @label:     Label to pass to gpiod_request()

> + *

> + * This function is a simple pass-through to acpi_get_gpiod(), except that

> + * as it is intended for use outside of the GPIO layer (in a similar fashion to

> + * gpiod_get_index() for example) it also holds a reference to the GPIO device.

> + */

> +struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label)

> +{

> +	struct gpio_desc *gpio;

> +	int ret;

> +

> +	gpio = acpi_get_gpiod(path, pin);

> +	if (IS_ERR(gpio))

> +		return gpio;

> +

> +	ret = gpiod_request(gpio, label);

> +	if (ret)

> +		return ERR_PTR(ret);

> +

> +	return gpio;

> +}

> +EXPORT_SYMBOL_GPL(acpi_get_and_request_gpiod);

> +

>  static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)

>  {

>  	struct acpi_gpio_event *event = data;

> diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h

> index c73b25bc9213..566feb56601f 100644

> --- a/include/linux/gpio/consumer.h

> +++ b/include/linux/gpio/consumer.h

> @@ -692,6 +692,8 @@ int devm_acpi_dev_add_driver_gpios(struct device *dev,

>  				   const struct acpi_gpio_mapping *gpios);

>  void devm_acpi_dev_remove_driver_gpios(struct device *dev);

>  

> +struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label);

> +

>  #else  /* CONFIG_GPIOLIB && CONFIG_ACPI */

>  

>  struct acpi_device;

> -- 

> 2.25.1

> 


-- 
With Best Regards,
Andy Shevchenko
Daniel Scally June 4, 2021, 2:09 p.m. UTC | #2
Hi Andy

On 04/06/2021 13:59, Andy Shevchenko wrote:
> On Thu, Jun 03, 2021 at 11:40:04PM +0100, Daniel Scally wrote:

>> We need to be able to translate GPIO resources in an ACPI device's _CRS

>> into GPIO descriptor array. Those are represented in _CRS as a pathname

>> to a GPIO device plus the pin's index number: the acpi_get_gpiod()

>> function is perfect for that purpose.

>>

>> As it's currently only used internally within the GPIO layer, provide and

>> export a wrapper function that additionally holds a reference to the GPIO

>> device.

> The subject is wrong, it should be "Introduce acpi_get_and_request_gpiod()

> helper" or so. I can fix when applying.



Ah! That was sloppy, sorry.

> Btw, do I understand correctly that I may push GPIO ACPI patches independently

> (of the ACPI changes)?



They're independent yes.

>

>> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

>> Signed-off-by: Daniel Scally <djrscally@gmail.com>

>> ---

>> Changes since v4:

>> 	- None

>>

>>  drivers/gpio/gpiolib-acpi.c   | 28 ++++++++++++++++++++++++++++

>>  include/linux/gpio/consumer.h |  2 ++

>>  2 files changed, 30 insertions(+)

>>

>> diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c

>> index 5b4111e4be3f..684ddb35d83b 100644

>> --- a/drivers/gpio/gpiolib-acpi.c

>> +++ b/drivers/gpio/gpiolib-acpi.c

>> @@ -128,6 +128,34 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)

>>  	return gpiochip_get_desc(chip, pin);

>>  }

>>  

>> +/**

>> + * acpi_get_and_request_gpiod() - Translate ACPI GPIO pin to GPIO descriptor

>> + *                               and hold a refcount to the GPIO device.

>> + * @path:      ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")

>> + * @pin:       ACPI GPIO pin number (0-based, controller-relative)

>> + * @label:     Label to pass to gpiod_request()

>> + *

>> + * This function is a simple pass-through to acpi_get_gpiod(), except that

>> + * as it is intended for use outside of the GPIO layer (in a similar fashion to

>> + * gpiod_get_index() for example) it also holds a reference to the GPIO device.

>> + */

>> +struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label)

>> +{

>> +	struct gpio_desc *gpio;

>> +	int ret;

>> +

>> +	gpio = acpi_get_gpiod(path, pin);

>> +	if (IS_ERR(gpio))

>> +		return gpio;

>> +

>> +	ret = gpiod_request(gpio, label);

>> +	if (ret)

>> +		return ERR_PTR(ret);

>> +

>> +	return gpio;

>> +}

>> +EXPORT_SYMBOL_GPL(acpi_get_and_request_gpiod);

>> +

>>  static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)

>>  {

>>  	struct acpi_gpio_event *event = data;

>> diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h

>> index c73b25bc9213..566feb56601f 100644

>> --- a/include/linux/gpio/consumer.h

>> +++ b/include/linux/gpio/consumer.h

>> @@ -692,6 +692,8 @@ int devm_acpi_dev_add_driver_gpios(struct device *dev,

>>  				   const struct acpi_gpio_mapping *gpios);

>>  void devm_acpi_dev_remove_driver_gpios(struct device *dev);

>>  

>> +struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label);

>> +

>>  #else  /* CONFIG_GPIOLIB && CONFIG_ACPI */

>>  

>>  struct acpi_device;

>> -- 

>> 2.25.1

>>
diff mbox series

Patch

diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 5b4111e4be3f..684ddb35d83b 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -128,6 +128,34 @@  static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
 	return gpiochip_get_desc(chip, pin);
 }
 
+/**
+ * acpi_get_and_request_gpiod() - Translate ACPI GPIO pin to GPIO descriptor
+ *                               and hold a refcount to the GPIO device.
+ * @path:      ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
+ * @pin:       ACPI GPIO pin number (0-based, controller-relative)
+ * @label:     Label to pass to gpiod_request()
+ *
+ * This function is a simple pass-through to acpi_get_gpiod(), except that
+ * as it is intended for use outside of the GPIO layer (in a similar fashion to
+ * gpiod_get_index() for example) it also holds a reference to the GPIO device.
+ */
+struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label)
+{
+	struct gpio_desc *gpio;
+	int ret;
+
+	gpio = acpi_get_gpiod(path, pin);
+	if (IS_ERR(gpio))
+		return gpio;
+
+	ret = gpiod_request(gpio, label);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return gpio;
+}
+EXPORT_SYMBOL_GPL(acpi_get_and_request_gpiod);
+
 static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
 {
 	struct acpi_gpio_event *event = data;
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index c73b25bc9213..566feb56601f 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -692,6 +692,8 @@  int devm_acpi_dev_add_driver_gpios(struct device *dev,
 				   const struct acpi_gpio_mapping *gpios);
 void devm_acpi_dev_remove_driver_gpios(struct device *dev);
 
+struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label);
+
 #else  /* CONFIG_GPIOLIB && CONFIG_ACPI */
 
 struct acpi_device;