gpio: pass lookup and descriptor flags to request_own
authorLinus Walleij <linus.walleij@linaro.org>
Fri, 26 Apr 2019 12:40:18 +0000 (14:40 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 7 Jun 2019 21:20:23 +0000 (23:20 +0200)
When a gpio_chip wants to request a descriptor from itself
using gpiochip_request_own_desc() it needs to be able to specify
fully how to use the descriptor, notably line inversion
semantics. The workaround in the gpiolib.c can be removed
and cases (such as SPI CS) where we need at times to request
a GPIO with line inversion semantics directly on a chip for
workarounds, can be fully supported with this call.

Fix up some users of the API that weren't really using the
last flag to set up the line as input or output properly
but instead just calling direction setting explicitly
after requesting the line.

Cc: Martin Sperl <kernel@martin.sperl.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
arch/arm/mach-omap1/ams-delta-fiq.c
arch/arm/mach-omap1/board-ams-delta.c
drivers/gpio/gpio-mvebu.c
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib.c
drivers/hid/hid-cp2112.c
drivers/memory/omap-gpmc.c
include/linux/gpio/driver.h

index 51212133ce06f68965012935da4ef6d4c1f3c4a8..46ca2d9d38efb1b17b6bea100798e02facbe49ae 100644 (file)
@@ -14,6 +14,7 @@
  * the Free Software Foundation.
  */
 #include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -102,7 +103,8 @@ 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], 0);
+               gpiod = gpiochip_request_own_desc(chip, i, pin_name[i],
+                                                 GPIO_ACTIVE_HIGH, GPIOD_IN);
                if (IS_ERR(gpiod)) {
                        pr_err("%s: failed to get GPIO pin %d (%ld)\n",
                               __func__, i, PTR_ERR(gpiod));
index b6e814166ee03615bbda86dfd039e0fda021d502..e49542540fc6907351564232cbd23d6198424a4a 100644 (file)
@@ -13,6 +13,7 @@
  */
 #include <linux/gpio/driver.h>
 #include <linux/gpio/machine.h>
+#include <linux/gpio/consumer.h>
 #include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -609,12 +610,12 @@ static void __init modem_assign_irq(struct gpio_chip *chip)
        struct gpio_desc *gpiod;
 
        gpiod = gpiochip_request_own_desc(chip, AMS_DELTA_GPIO_PIN_MODEM_IRQ,
-                                         "modem_irq", 0);
+                                         "modem_irq", GPIO_ACTIVE_HIGH,
+                                         GPIOD_IN);
        if (IS_ERR(gpiod)) {
                pr_err("%s: modem IRQ GPIO request failed (%ld)\n", __func__,
                       PTR_ERR(gpiod));
        } else {
-               gpiod_direction_input(gpiod);
                ams_delta_modem_ports[0].irq = gpiod_to_irq(gpiod);
        }
 }
index 059094ac44cb38458ecfce964041450f409bf039..869d47f895996efe4e73c78bc8e7dfe38df3668b 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/irq.h>
@@ -618,18 +619,14 @@ 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", 0);
+                                                pwm->hwpwm, "mvebu-pwm",
+                                                GPIO_ACTIVE_HIGH,
+                                                GPIOD_OUT_LOW);
                if (IS_ERR(desc)) {
                        ret = PTR_ERR(desc);
                        goto out;
                }
 
-               ret = gpiod_direction_output(desc, 0);
-               if (ret) {
-                       gpiochip_free_own_desc(desc);
-                       goto out;
-               }
-
                mvpwm->gpiod = desc;
        }
 out:
index c9fc9e232aafb37d67c7b72b83183b778963d41a..39f2f9035c11df2b7c0d7446745a0c83cf7e0cc2 100644 (file)
@@ -217,14 +217,13 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
        if (!handler)
                return AE_OK;
 
-       desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event", 0);
+       desc = gpiochip_request_own_desc(chip, pin, "ACPI:Event",
+                                        GPIO_ACTIVE_HIGH, GPIOD_IN);
        if (IS_ERR(desc)) {
                dev_err(chip->parent, "Failed to request GPIO\n");
                return AE_ERROR;
        }
 
-       gpiod_direction_input(desc);
-
        ret = gpiochip_lock_as_irq(chip, pin);
        if (ret) {
                dev_err(chip->parent, "Failed to lock GPIO as interrupt\n");
@@ -951,6 +950,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
                        const char *label = "ACPI:OpRegion";
 
                        desc = gpiochip_request_own_desc(chip, pin, label,
+                                                        GPIO_ACTIVE_HIGH,
                                                         flags);
                        if (IS_ERR(desc)) {
                                status = AE_ERROR;
index e013d417a9361c5d19f340bf7a69ce2627781519..4561cb39bdb45fe34c5a47c31a10bec94e3424fd 100644 (file)
@@ -2503,7 +2503,11 @@ 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
+ * @lflags: lookup flags for this GPIO or 0 if default, this can be used to
+ * specify things like line inversion semantics with the machine flags
+ * such as GPIO_OUT_LOW
+ * @dflags: descriptor request flags for this GPIO or 0 if default, this
+ * can be used to specify consumer semantics such as open drain
  *
  * Function allows GPIO chip drivers to request and use their own GPIO
  * descriptors via gpiolib API. Difference to gpiod_request() is that this
@@ -2517,9 +2521,9 @@ EXPORT_SYMBOL_GPL(gpiochip_is_requested);
  */
 struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
                                            const char *label,
-                                           enum gpiod_flags flags)
+                                           enum gpio_lookup_flags lflags,
+                                           enum gpiod_flags dflags)
 {
-       unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
        struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum);
        int err;
 
@@ -2532,7 +2536,7 @@ 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, lflags, flags);
+       err = gpiod_configure_flags(desc, label, lflags, dflags);
        if (err) {
                chip_err(chip, "setup of own GPIO %s failed\n", label);
                gpiod_free_commit(desc);
@@ -4420,15 +4424,8 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
        chip = gpiod_to_chip(desc);
        hwnum = gpio_chip_hwgpio(desc);
 
-       /*
-        * 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);
+       local_desc = gpiochip_request_own_desc(chip, hwnum, name,
+                                              lflags, dflags);
        if (IS_ERR(local_desc)) {
                status = PTR_ERR(local_desc);
                pr_err("requesting hog GPIO %s (chip %s, offset %d) failed, %d\n",
@@ -4436,14 +4433,6 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
                return status;
        }
 
-       status = gpiod_configure_flags(desc, name, lflags, dflags);
-       if (status < 0) {
-               pr_err("setup of hog GPIO %s (chip %s, offset %d) failed, %d\n",
-                      name, chip->label, hwnum, status);
-               gpiochip_free_own_desc(desc);
-               return status;
-       }
-
        /* Mark GPIO as hogged so it can be identified and removed later */
        set_bit(FLAG_IS_HOGGED, &desc->flags);
 
index 47f65857408df5c3e7d0bce84060ce57b3c8f3ae..f6fb97a14de6f0f6f634d470dcdc5b98d091a1ee 100644 (file)
@@ -24,7 +24,8 @@
  *   https://www.silabs.com/documents/public/application-notes/an495-cp2112-interface-specification.pdf
  */
 
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio/driver.h>
 #include <linux/hid.h>
 #include <linux/hidraw.h>
@@ -1203,7 +1204,9 @@ 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", 0);
+                                                  "HID/I2C:Event",
+                                                  GPIO_ACTIVE_HIGH,
+                                                  GPIOD_IN);
        if (IS_ERR(dev->desc[pin])) {
                dev_err(dev->gc.parent, "Failed to request GPIO\n");
                return PTR_ERR(dev->desc[pin]);
index f6297599433f14ee73259aa34b54cbf9eb538c9d..f4f98957dc86b7407d9944a47764b410c5c129be 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/consumer.h> /* GPIO descriptor enum */
+#include <linux/gpio/machine.h>
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
 #include <linux/platform_device.h>
@@ -2172,7 +2173,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 
                waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip,
                                                         wait_pin, "WAITPIN",
-                                                        0);
+                                                        GPIO_ACTIVE_HIGH,
+                                                        GPIOD_IN);
                if (IS_ERR(waitpin_desc)) {
                        dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin);
                        ret = PTR_ERR(waitpin_desc);
index a1d273c96016ad2764d04467b007c2667f763749..937c40fb61f7e727d6c89b219c90bc40823a26d1 100644 (file)
@@ -18,6 +18,7 @@ struct seq_file;
 struct gpio_device;
 struct module;
 enum gpiod_flags;
+enum gpio_lookup_flags;
 
 #ifdef CONFIG_GPIOLIB
 
@@ -614,7 +615,8 @@ gpiochip_remove_pin_ranges(struct gpio_chip *chip)
 
 struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
                                            const char *label,
-                                           enum gpiod_flags flags);
+                                           enum gpio_lookup_flags lflags,
+                                           enum gpiod_flags dflags);
 void gpiochip_free_own_desc(struct gpio_desc *desc);
 
 void devprop_gpiochip_set_names(struct gpio_chip *chip,