gpio: Pass a flag to gpiochip_request_own_desc()

Message ID 20180904113752.16804-1-linus.walleij@linaro.org
State New
Headers show
Series
  • gpio: Pass a flag to gpiochip_request_own_desc()
Related show

Commit Message

Linus Walleij Sept. 4, 2018, 11:37 a.m.
Before things go out of hand, make it possible to pass
flags when requesting "own" descriptors from a gpio_chip.
This is necessary if the chip wants to reques a GPIO with
active low semantics, for example.

Cc: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Cc: Gregory CLEMENT <gregory.clement@free-electrons.com>
Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Roger Quadros <rogerq@ti.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

---
 Documentation/driver-api/gpio/driver.rst |  4 +++-
 arch/arm/mach-omap1/ams-delta-fiq.c      |  2 +-
 arch/arm/mach-omap1/board-ams-delta.c    |  2 +-
 drivers/gpio/gpio-mvebu.c                |  2 +-
 drivers/gpio/gpiolib-acpi.c              | 13 +++----------
 drivers/gpio/gpiolib.c                   | 21 +++++++++++++++++++--
 drivers/hid/hid-cp2112.c                 |  2 +-
 drivers/memory/omap-gpmc.c               |  3 ++-
 include/linux/gpio/driver.h              |  4 +++-
 9 files changed, 34 insertions(+), 19 deletions(-)

-- 
2.17.1

Comments

Gregory CLEMENT Sept. 21, 2018, 2:20 p.m. | #1
Hi Linus,
 
 On mar., sept. 04 2018, Linus Walleij <linus.walleij@linaro.org> wrote:

> Before things go out of hand, make it possible to pass

> flags when requesting "own" descriptors from a gpio_chip.

> This is necessary if the chip wants to reques a GPIO with

> active low semantics, for example.


For mvebu:

Reviewed-by: Gregory CLEMENT <gregory.clement@bootlin.com>


Thanks,

Gregory


>

> Cc: Janusz Krzysztofik <jmkrzyszt@gmail.com>

> Cc: Gregory CLEMENT <gregory.clement@free-electrons.com>

> Cc: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

> Cc: Jason Cooper <jason@lakedaemon.net>

> Cc: Jiri Kosina <jkosina@suse.cz>

> Cc: Roger Quadros <rogerq@ti.com>

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

> ---

>  Documentation/driver-api/gpio/driver.rst |  4 +++-

>  arch/arm/mach-omap1/ams-delta-fiq.c      |  2 +-

>  arch/arm/mach-omap1/board-ams-delta.c    |  2 +-

>  drivers/gpio/gpio-mvebu.c                |  2 +-

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

>  drivers/gpio/gpiolib.c                   | 21 +++++++++++++++++++--

>  drivers/hid/hid-cp2112.c                 |  2 +-

>  drivers/memory/omap-gpmc.c               |  3 ++-

>  include/linux/gpio/driver.h              |  4 +++-

>  9 files changed, 34 insertions(+), 19 deletions(-)

>

> diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst

> index cbe0242842d1..e9a5aae8c84c 100644

> --- a/Documentation/driver-api/gpio/driver.rst

> +++ b/Documentation/driver-api/gpio/driver.rst

> @@ -413,7 +413,9 @@ try_module_get()). A GPIO driver can use the following functions instead

>  to request and free descriptors without being pinned to the kernel forever::

>  

>  	struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,

> -						    const char *label)

> +						    u16 hwnum,

> +						    const char *label,

> +						    enum gpiod_flags flags)

>  

>  	void gpiochip_free_own_desc(struct gpio_desc *desc)

>  

> diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c

> index b0dc7ddf5877..0324d0f209ea 100644

> --- a/arch/arm/mach-omap1/ams-delta-fiq.c

> +++ b/arch/arm/mach-omap1/ams-delta-fiq.c

> @@ -103,7 +103,7 @@ void __init ams_delta_init_fiq(struct gpio_chip *chip,

>  	}

>  

>  	for (i = 0; i < ARRAY_SIZE(irq_data); i++) {

> -		gpiod = gpiochip_request_own_desc(chip, i, pin_name[i]);

> +		gpiod = gpiochip_request_own_desc(chip, i, pin_name[i], 0);

>  		if (IS_ERR(gpiod)) {

>  			pr_err("%s: failed to get GPIO pin %d (%ld)\n",

>  			       __func__, i, PTR_ERR(gpiod));

> diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c

> index dd28d2614d7f..085438d17662 100644

> --- a/arch/arm/mach-omap1/board-ams-delta.c

> +++ b/arch/arm/mach-omap1/board-ams-delta.c

> @@ -784,7 +784,7 @@ static void __init ams_delta_led_init(struct gpio_chip *chip)

>  	int i;

>  

>  	for (i = LATCH1_PIN_LED_CAMERA; i < LATCH1_PIN_DOCKIT1; i++) {

> -		gpiod = gpiochip_request_own_desc(chip, i, NULL);

> +		gpiod = gpiochip_request_own_desc(chip, i, "camera-led", 0);

>  		if (IS_ERR(gpiod)) {

>  			pr_warn("%s: %s GPIO %d request failed (%ld)\n",

>  				__func__, LATCH1_LABEL, i, PTR_ERR(gpiod));

> diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c

> index 6e02148c208b..6c675c5accba 100644

> --- a/drivers/gpio/gpio-mvebu.c

> +++ b/drivers/gpio/gpio-mvebu.c

> @@ -608,7 +608,7 @@ static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)

>  		ret = -EBUSY;

>  	} else {

>  		desc = gpiochip_request_own_desc(&mvchip->chip,

> -						 pwm->hwpwm, "mvebu-pwm");

> +						 pwm->hwpwm, "mvebu-pwm", 0);

>  		if (IS_ERR(desc)) {

>  			ret = PTR_ERR(desc);

>  			goto out;

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

> index c48ed9d89ff5..2b76ccaf0350 100644

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

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

> @@ -178,7 +178,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,

>  	if (!handler)

>  		return AE_OK;

>  

> -	desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event");

> +	desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event", 0);

>  	if (IS_ERR(desc)) {

>  		dev_err(chip->parent, "Failed to request GPIO\n");

>  		return AE_ERROR;

> @@ -883,21 +883,14 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,

>  			const char *label = "ACPI:OpRegion";

>  			int err;

>  

> -			desc = gpiochip_request_own_desc(chip, pin, label);

> +			desc = gpiochip_request_own_desc(chip, pin, label,

> +							 0, flags);

>  			if (IS_ERR(desc)) {

>  				status = AE_ERROR;

>  				mutex_unlock(&achip->conn_lock);

>  				goto out;

>  			}

>  

> -			err = gpiod_configure_flags(desc, label, 0, flags);

> -			if (err < 0) {

> -				status = AE_NOT_CONFIGURED;

> -				gpiochip_free_own_desc(desc);

> -				mutex_unlock(&achip->conn_lock);

> -				goto out;

> -			}

> -

>  			conn = kzalloc(sizeof(*conn), GFP_KERNEL);

>  			if (!conn) {

>  				status = AE_NO_MEMORY;

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

> index e8f8a1999393..26e2ec06eb43 100644

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

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

> @@ -2446,6 +2446,7 @@ EXPORT_SYMBOL_GPL(gpiochip_is_requested);

>   * @chip: GPIO chip

>   * @hwnum: hardware number of the GPIO for which to request the descriptor

>   * @label: label for the GPIO

> + * @flags: flags for this GPIO or 0 if default

>   *

>   * Function allows GPIO chip drivers to request and use their own GPIO

>   * descriptors via gpiolib API. Difference to gpiod_request() is that this

> @@ -2458,7 +2459,8 @@ EXPORT_SYMBOL_GPL(gpiochip_is_requested);

>   * code on failure.

>   */

>  struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,

> -					    const char *label)

> +					    const char *label,

> +					    enum gpiod_flags flags)

>  {

>  	struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum);

>  	int err;

> @@ -2472,6 +2474,13 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,

>  	if (err < 0)

>  		return ERR_PTR(err);

>  

> +	err = gpiod_configure_flags(desc, label, 0, flags);

> +	if (err) {

> +		chip_err(chip, "setup of own GPIO %s failed\n", label);

> +		gpiod_free_commit(desc);

> +		return ERR_PTR(err);

> +	}

> +

>  	return desc;

>  }

>  EXPORT_SYMBOL_GPL(gpiochip_request_own_desc);

> @@ -4108,7 +4117,15 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,

>  	chip = gpiod_to_chip(desc);

>  	hwnum = gpio_chip_hwgpio(desc);

>  

> -	local_desc = gpiochip_request_own_desc(chip, hwnum, name);

> +	/*

> +	 * FIXME: not very elegant that we call gpiod_configure_flags()

> +	 * twice here (once inside gpiochip_request_own_desc() and

> +	 * again here), but the gpiochip_request_own_desc() is external

> +	 * and cannot really pass the lflags so this is the lesser evil

> +	 * at the moment. Pass zero as dflags on this first call so we

> +	 * don't screw anything up.

> +	 */

> +	local_desc = gpiochip_request_own_desc(chip, hwnum, name, 0);

>  	if (IS_ERR(local_desc)) {

>  		status = PTR_ERR(local_desc);

>  		pr_err("requesting hog GPIO %s (chip %s, offset %d) failed, %d\n",

> diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c

> index 271f31461da4..47f65857408d 100644

> --- a/drivers/hid/hid-cp2112.c

> +++ b/drivers/hid/hid-cp2112.c

> @@ -1203,7 +1203,7 @@ static int __maybe_unused cp2112_allocate_irq(struct cp2112_device *dev,

>  		return -EINVAL;

>  

>  	dev->desc[pin] = gpiochip_request_own_desc(&dev->gc, pin,

> -						   "HID/I2C:Event");

> +						   "HID/I2C:Event", 0);

>  	if (IS_ERR(dev->desc[pin])) {

>  		dev_err(dev->gc.parent, "Failed to request GPIO\n");

>  		return PTR_ERR(dev->desc[pin]);

> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c

> index c215287e80cf..b9b4f7058b05 100644

> --- a/drivers/memory/omap-gpmc.c

> +++ b/drivers/memory/omap-gpmc.c

> @@ -2170,7 +2170,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,

>  		unsigned int wait_pin = gpmc_s.wait_pin;

>  

>  		waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip,

> -							 wait_pin, "WAITPIN");

> +							 wait_pin, "WAITPIN",

> +							 0);

>  		if (IS_ERR(waitpin_desc)) {

>  			dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin);

>  			ret = PTR_ERR(waitpin_desc);

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

> index 0ea328e71ec9..86d9db466444 100644

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

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

> @@ -17,6 +17,7 @@ struct device_node;

>  struct seq_file;

>  struct gpio_device;

>  struct module;

> +enum gpiod_flags;

>  

>  #ifdef CONFIG_GPIOLIB

>  

> @@ -570,7 +571,8 @@ gpiochip_remove_pin_ranges(struct gpio_chip *chip)

>  #endif /* CONFIG_PINCTRL */

>  

>  struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,

> -					    const char *label);

> +					    const char *label,

> +					    enum gpiod_flags flags);

>  void gpiochip_free_own_desc(struct gpio_desc *desc);

>  

>  #else /* CONFIG_GPIOLIB */

> -- 

> 2.17.1

>


-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com

Patch

diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst
index cbe0242842d1..e9a5aae8c84c 100644
--- a/Documentation/driver-api/gpio/driver.rst
+++ b/Documentation/driver-api/gpio/driver.rst
@@ -413,7 +413,9 @@  try_module_get()). A GPIO driver can use the following functions instead
 to request and free descriptors without being pinned to the kernel forever::
 
 	struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,
-						    const char *label)
+						    u16 hwnum,
+						    const char *label,
+						    enum gpiod_flags flags)
 
 	void gpiochip_free_own_desc(struct gpio_desc *desc)
 
diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c
index b0dc7ddf5877..0324d0f209ea 100644
--- a/arch/arm/mach-omap1/ams-delta-fiq.c
+++ b/arch/arm/mach-omap1/ams-delta-fiq.c
@@ -103,7 +103,7 @@  void __init ams_delta_init_fiq(struct gpio_chip *chip,
 	}
 
 	for (i = 0; i < ARRAY_SIZE(irq_data); i++) {
-		gpiod = gpiochip_request_own_desc(chip, i, pin_name[i]);
+		gpiod = gpiochip_request_own_desc(chip, i, pin_name[i], 0);
 		if (IS_ERR(gpiod)) {
 			pr_err("%s: failed to get GPIO pin %d (%ld)\n",
 			       __func__, i, PTR_ERR(gpiod));
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index dd28d2614d7f..085438d17662 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -784,7 +784,7 @@  static void __init ams_delta_led_init(struct gpio_chip *chip)
 	int i;
 
 	for (i = LATCH1_PIN_LED_CAMERA; i < LATCH1_PIN_DOCKIT1; i++) {
-		gpiod = gpiochip_request_own_desc(chip, i, NULL);
+		gpiod = gpiochip_request_own_desc(chip, i, "camera-led", 0);
 		if (IS_ERR(gpiod)) {
 			pr_warn("%s: %s GPIO %d request failed (%ld)\n",
 				__func__, LATCH1_LABEL, i, PTR_ERR(gpiod));
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
index 6e02148c208b..6c675c5accba 100644
--- a/drivers/gpio/gpio-mvebu.c
+++ b/drivers/gpio/gpio-mvebu.c
@@ -608,7 +608,7 @@  static int mvebu_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 		ret = -EBUSY;
 	} else {
 		desc = gpiochip_request_own_desc(&mvchip->chip,
-						 pwm->hwpwm, "mvebu-pwm");
+						 pwm->hwpwm, "mvebu-pwm", 0);
 		if (IS_ERR(desc)) {
 			ret = PTR_ERR(desc);
 			goto out;
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index c48ed9d89ff5..2b76ccaf0350 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -178,7 +178,7 @@  static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
 	if (!handler)
 		return AE_OK;
 
-	desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event");
+	desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event", 0);
 	if (IS_ERR(desc)) {
 		dev_err(chip->parent, "Failed to request GPIO\n");
 		return AE_ERROR;
@@ -883,21 +883,14 @@  acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
 			const char *label = "ACPI:OpRegion";
 			int err;
 
-			desc = gpiochip_request_own_desc(chip, pin, label);
+			desc = gpiochip_request_own_desc(chip, pin, label,
+							 0, flags);
 			if (IS_ERR(desc)) {
 				status = AE_ERROR;
 				mutex_unlock(&achip->conn_lock);
 				goto out;
 			}
 
-			err = gpiod_configure_flags(desc, label, 0, flags);
-			if (err < 0) {
-				status = AE_NOT_CONFIGURED;
-				gpiochip_free_own_desc(desc);
-				mutex_unlock(&achip->conn_lock);
-				goto out;
-			}
-
 			conn = kzalloc(sizeof(*conn), GFP_KERNEL);
 			if (!conn) {
 				status = AE_NO_MEMORY;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e8f8a1999393..26e2ec06eb43 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2446,6 +2446,7 @@  EXPORT_SYMBOL_GPL(gpiochip_is_requested);
  * @chip: GPIO chip
  * @hwnum: hardware number of the GPIO for which to request the descriptor
  * @label: label for the GPIO
+ * @flags: flags for this GPIO or 0 if default
  *
  * Function allows GPIO chip drivers to request and use their own GPIO
  * descriptors via gpiolib API. Difference to gpiod_request() is that this
@@ -2458,7 +2459,8 @@  EXPORT_SYMBOL_GPL(gpiochip_is_requested);
  * code on failure.
  */
 struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
-					    const char *label)
+					    const char *label,
+					    enum gpiod_flags flags)
 {
 	struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum);
 	int err;
@@ -2472,6 +2474,13 @@  struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
 	if (err < 0)
 		return ERR_PTR(err);
 
+	err = gpiod_configure_flags(desc, label, 0, flags);
+	if (err) {
+		chip_err(chip, "setup of own GPIO %s failed\n", label);
+		gpiod_free_commit(desc);
+		return ERR_PTR(err);
+	}
+
 	return desc;
 }
 EXPORT_SYMBOL_GPL(gpiochip_request_own_desc);
@@ -4108,7 +4117,15 @@  int gpiod_hog(struct gpio_desc *desc, const char *name,
 	chip = gpiod_to_chip(desc);
 	hwnum = gpio_chip_hwgpio(desc);
 
-	local_desc = gpiochip_request_own_desc(chip, hwnum, name);
+	/*
+	 * FIXME: not very elegant that we call gpiod_configure_flags()
+	 * twice here (once inside gpiochip_request_own_desc() and
+	 * again here), but the gpiochip_request_own_desc() is external
+	 * and cannot really pass the lflags so this is the lesser evil
+	 * at the moment. Pass zero as dflags on this first call so we
+	 * don't screw anything up.
+	 */
+	local_desc = gpiochip_request_own_desc(chip, hwnum, name, 0);
 	if (IS_ERR(local_desc)) {
 		status = PTR_ERR(local_desc);
 		pr_err("requesting hog GPIO %s (chip %s, offset %d) failed, %d\n",
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
index 271f31461da4..47f65857408d 100644
--- a/drivers/hid/hid-cp2112.c
+++ b/drivers/hid/hid-cp2112.c
@@ -1203,7 +1203,7 @@  static int __maybe_unused cp2112_allocate_irq(struct cp2112_device *dev,
 		return -EINVAL;
 
 	dev->desc[pin] = gpiochip_request_own_desc(&dev->gc, pin,
-						   "HID/I2C:Event");
+						   "HID/I2C:Event", 0);
 	if (IS_ERR(dev->desc[pin])) {
 		dev_err(dev->gc.parent, "Failed to request GPIO\n");
 		return PTR_ERR(dev->desc[pin]);
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index c215287e80cf..b9b4f7058b05 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -2170,7 +2170,8 @@  static int gpmc_probe_generic_child(struct platform_device *pdev,
 		unsigned int wait_pin = gpmc_s.wait_pin;
 
 		waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip,
-							 wait_pin, "WAITPIN");
+							 wait_pin, "WAITPIN",
+							 0);
 		if (IS_ERR(waitpin_desc)) {
 			dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin);
 			ret = PTR_ERR(waitpin_desc);
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 0ea328e71ec9..86d9db466444 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -17,6 +17,7 @@  struct device_node;
 struct seq_file;
 struct gpio_device;
 struct module;
+enum gpiod_flags;
 
 #ifdef CONFIG_GPIOLIB
 
@@ -570,7 +571,8 @@  gpiochip_remove_pin_ranges(struct gpio_chip *chip)
 #endif /* CONFIG_PINCTRL */
 
 struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
-					    const char *label);
+					    const char *label,
+					    enum gpiod_flags flags);
 void gpiochip_free_own_desc(struct gpio_desc *desc);
 
 #else /* CONFIG_GPIOLIB */