Merge tag 'gpio-v5.11-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[sfrench/cifs-2.6.git] / drivers / gpio / gpiolib.c
index 6e3c4d7a7d14675b47c576b1b09165ca7d929877..b02cc2abd3b680263cdc9c5cd11c278969c9b9ee 100644 (file)
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+
 #include <linux/bitmap.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -119,7 +120,7 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
        spin_unlock_irqrestore(&gpio_lock, flags);
 
        if (!gpio_is_valid(gpio))
-               WARN(1, "invalid GPIO %d\n", gpio);
+               pr_warn("invalid GPIO %d\n", gpio);
 
        return NULL;
 }
@@ -211,7 +212,7 @@ static int gpiochip_find_base(int ngpio)
 int gpiod_get_direction(struct gpio_desc *desc)
 {
        struct gpio_chip *gc;
-       unsigned offset;
+       unsigned int offset;
        int ret;
 
        gc = gpiod_to_chip(desc);
@@ -771,9 +772,11 @@ err_free_ida:
        ida_free(&gpio_ida, gdev->id);
 err_free_gdev:
        /* failures here can mean systems won't boot... */
-       pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
-              gdev->base, gdev->base + gdev->ngpio - 1,
-              gc->label ? : "generic", ret);
+       if (ret != -EPROBE_DEFER) {
+               pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
+                      gdev->base, gdev->base + gdev->ngpio - 1,
+                      gc->label ? : "generic", ret);
+       }
        kfree(gdev);
        return ret;
 }
@@ -936,67 +939,6 @@ bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gc,
 }
 EXPORT_SYMBOL_GPL(gpiochip_irqchip_irq_valid);
 
-/**
- * gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip
- * @gc: the gpiochip to set the irqchip chain to
- * @parent_irq: the irq number corresponding to the parent IRQ for this
- * cascaded irqchip
- * @parent_handler: the parent interrupt handler for the accumulated IRQ
- * coming out of the gpiochip. If the interrupt is nested rather than
- * cascaded, pass NULL in this handler argument
- */
-static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gc,
-                                         unsigned int parent_irq,
-                                         irq_flow_handler_t parent_handler)
-{
-       struct gpio_irq_chip *girq = &gc->irq;
-       struct device *dev = &gc->gpiodev->dev;
-
-       if (!girq->domain) {
-               chip_err(gc, "called %s before setting up irqchip\n",
-                        __func__);
-               return;
-       }
-
-       if (parent_handler) {
-               if (gc->can_sleep) {
-                       chip_err(gc,
-                                "you cannot have chained interrupts on a chip that may sleep\n");
-                       return;
-               }
-               girq->parents = devm_kcalloc(dev, 1,
-                                            sizeof(*girq->parents),
-                                            GFP_KERNEL);
-               if (!girq->parents) {
-                       chip_err(gc, "out of memory allocating parent IRQ\n");
-                       return;
-               }
-               girq->parents[0] = parent_irq;
-               girq->num_parents = 1;
-               /*
-                * The parent irqchip is already using the chip_data for this
-                * irqchip, so our callbacks simply use the handler_data.
-                */
-               irq_set_chained_handler_and_data(parent_irq, parent_handler,
-                                                gc);
-       }
-}
-
-/**
- * gpiochip_set_nested_irqchip() - connects a nested irqchip to a gpiochip
- * @gc: the gpiochip to set the irqchip nested handler to
- * @irqchip: the irqchip to nest to the gpiochip
- * @parent_irq: the irq number corresponding to the parent IRQ for this
- * nested irqchip
- */
-void gpiochip_set_nested_irqchip(struct gpio_chip *gc,
-                                struct irq_chip *irqchip,
-                                unsigned int parent_irq)
-{
-       gpiochip_set_cascaded_irqchip(gc, parent_irq, NULL);
-}
-EXPORT_SYMBOL_GPL(gpiochip_set_nested_irqchip);
-
 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
 
 /**
@@ -1394,7 +1336,7 @@ void gpiochip_irq_domain_deactivate(struct irq_domain *domain,
 }
 EXPORT_SYMBOL_GPL(gpiochip_irq_domain_deactivate);
 
-static int gpiochip_to_irq(struct gpio_chip *gc, unsigned offset)
+static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset)
 {
        struct irq_domain *domain = gc->irq.domain;
 
@@ -1477,7 +1419,8 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gc)
        if (WARN_ON(gc->irq.irq_enable))
                return;
        /* Check if the irqchip already has this hook... */
-       if (irqchip->irq_enable == gpiochip_irq_enable) {
+       if (irqchip->irq_enable == gpiochip_irq_enable ||
+               irqchip->irq_mask == gpiochip_irq_mask) {
                /*
                 * ...and if so, give a gentle warning that this is bad
                 * practice.
@@ -1647,98 +1590,6 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gc)
        gpiochip_irqchip_free_valid_mask(gc);
 }
 
-/**
- * gpiochip_irqchip_add_key() - adds an irqchip to a gpiochip
- * @gc: the gpiochip to add the irqchip to
- * @irqchip: the irqchip to add to the gpiochip
- * @first_irq: if not dynamically assigned, the base (first) IRQ to
- * allocate gpiochip irqs from
- * @handler: the irq handler to use (often a predefined irq core function)
- * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE
- * to have the core avoid setting up any default type in the hardware.
- * @threaded: whether this irqchip uses a nested thread handler
- * @lock_key: lockdep class for IRQ lock
- * @request_key: lockdep class for IRQ request
- *
- * This function closely associates a certain irqchip with a certain
- * gpiochip, providing an irq domain to translate the local IRQs to
- * global irqs in the gpiolib core, and making sure that the gpiochip
- * is passed as chip data to all related functions. Driver callbacks
- * need to use gpiochip_get_data() to get their local state containers back
- * from the gpiochip passed as chip data. An irqdomain will be stored
- * in the gpiochip that shall be used by the driver to handle IRQ number
- * translation. The gpiochip will need to be initialized and registered
- * before calling this function.
- *
- * This function will handle two cell:ed simple IRQs and assumes all
- * the pins on the gpiochip can generate a unique IRQ. Everything else
- * need to be open coded.
- */
-int gpiochip_irqchip_add_key(struct gpio_chip *gc,
-                            struct irq_chip *irqchip,
-                            unsigned int first_irq,
-                            irq_flow_handler_t handler,
-                            unsigned int type,
-                            bool threaded,
-                            struct lock_class_key *lock_key,
-                            struct lock_class_key *request_key)
-{
-       struct device_node *of_node;
-
-       if (!gc || !irqchip)
-               return -EINVAL;
-
-       if (!gc->parent) {
-               chip_err(gc, "missing gpiochip .dev parent pointer\n");
-               return -EINVAL;
-       }
-       gc->irq.threaded = threaded;
-       of_node = gc->parent->of_node;
-#ifdef CONFIG_OF_GPIO
-       /*
-        * If the gpiochip has an assigned OF node this takes precedence
-        * FIXME: get rid of this and use gc->parent->of_node
-        * everywhere
-        */
-       if (gc->of_node)
-               of_node = gc->of_node;
-#endif
-       /*
-        * Specifying a default trigger is a terrible idea if DT or ACPI is
-        * used to configure the interrupts, as you may end-up with
-        * conflicting triggers. Tell the user, and reset to NONE.
-        */
-       if (WARN(of_node && type != IRQ_TYPE_NONE,
-                "%pOF: Ignoring %d default trigger\n", of_node, type))
-               type = IRQ_TYPE_NONE;
-       if (has_acpi_companion(gc->parent) && type != IRQ_TYPE_NONE) {
-               acpi_handle_warn(ACPI_HANDLE(gc->parent),
-                                "Ignoring %d default trigger\n", type);
-               type = IRQ_TYPE_NONE;
-       }
-
-       gc->irq.chip = irqchip;
-       gc->irq.handler = handler;
-       gc->irq.default_type = type;
-       gc->to_irq = gpiochip_to_irq;
-       gc->irq.lock_key = lock_key;
-       gc->irq.request_key = request_key;
-       gc->irq.domain = irq_domain_add_simple(of_node,
-                                       gc->ngpio, first_irq,
-                                       &gpiochip_domain_ops, gc);
-       if (!gc->irq.domain) {
-               gc->irq.chip = NULL;
-               return -EINVAL;
-       }
-
-       gpiochip_set_irq_hooks(gc);
-
-       acpi_gpiochip_request_interrupts(gc);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key);
-
 /**
  * gpiochip_irqchip_add_domain() - adds an irqdomain to a gpiochip
  * @gc: the gpiochip to add the irqchip to
@@ -1788,7 +1639,7 @@ static inline void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc)
  * @gc: the gpiochip owning the GPIO
  * @offset: the offset of the GPIO to request for GPIO function
  */
-int gpiochip_generic_request(struct gpio_chip *gc, unsigned offset)
+int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset)
 {
 #ifdef CONFIG_PINCTRL
        if (list_empty(&gc->gpiodev->pin_ranges))
@@ -1804,7 +1655,7 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request);
  * @gc: the gpiochip to request the gpio function for
  * @offset: the offset of the GPIO to free from GPIO function
  */
-void gpiochip_generic_free(struct gpio_chip *gc, unsigned offset)
+void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset)
 {
 #ifdef CONFIG_PINCTRL
        if (list_empty(&gc->gpiodev->pin_ranges))
@@ -1821,7 +1672,7 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_free);
  * @offset: the offset of the GPIO to apply the configuration
  * @config: the configuration to be applied
  */
-int gpiochip_generic_config(struct gpio_chip *gc, unsigned offset,
+int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset,
                            unsigned long config)
 {
        return pinctrl_gpio_set_config(gc->gpiodev->base + offset, config);
@@ -1985,11 +1836,9 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
 
        if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
                desc_set_label(desc, label ? : "?");
-               ret = 0;
        } else {
-               kfree_const(label);
                ret = -EBUSY;
-               goto done;
+               goto out_free_unlock;
        }
 
        if (gc->request) {
@@ -2002,11 +1851,10 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
                        ret = -EINVAL;
                spin_lock_irqsave(&gpio_lock, flags);
 
-               if (ret < 0) {
+               if (ret) {
                        desc_set_label(desc, NULL);
-                       kfree_const(label);
                        clear_bit(FLAG_REQUESTED, &desc->flags);
-                       goto done;
+                       goto out_free_unlock;
                }
        }
        if (gc->get_direction) {
@@ -2015,8 +1863,12 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
                gpiod_get_direction(desc);
                spin_lock_irqsave(&gpio_lock, flags);
        }
-done:
        spin_unlock_irqrestore(&gpio_lock, flags);
+       return 0;
+
+out_free_unlock:
+       spin_unlock_irqrestore(&gpio_lock, flags);
+       kfree_const(label);
        return ret;
 }
 
@@ -2068,7 +1920,7 @@ int gpiod_request(struct gpio_desc *desc, const char *label)
 
        if (try_module_get(gdev->owner)) {
                ret = gpiod_request_commit(desc, label);
-               if (ret < 0)
+               if (ret)
                        module_put(gdev->owner);
                else
                        get_device(&gdev->dev);
@@ -2151,7 +2003,7 @@ void gpiod_free(struct gpio_desc *desc)
  * help with diagnostics, and knowing that the signal is used as a GPIO
  * can help avoid accidentally multiplexing it to another controller.
  */
-const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned offset)
+const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned int offset)
 {
        struct gpio_desc *desc;
 
@@ -2251,30 +2103,49 @@ static int gpio_do_set_config(struct gpio_chip *gc, unsigned int offset,
        return gc->set_config(gc, offset, config);
 }
 
-static int gpio_set_config(struct gpio_desc *desc, enum pin_config_param mode)
+static int gpio_set_config_with_argument(struct gpio_desc *desc,
+                                        enum pin_config_param mode,
+                                        u32 argument)
 {
        struct gpio_chip *gc = desc->gdev->chip;
        unsigned long config;
-       unsigned arg;
+
+       config = pinconf_to_config_packed(mode, argument);
+       return gpio_do_set_config(gc, gpio_chip_hwgpio(desc), config);
+}
+
+static int gpio_set_config_with_argument_optional(struct gpio_desc *desc,
+                                                 enum pin_config_param mode,
+                                                 u32 argument)
+{
+       struct device *dev = &desc->gdev->dev;
+       int gpio = gpio_chip_hwgpio(desc);
+       int ret;
+
+       ret = gpio_set_config_with_argument(desc, mode, argument);
+       if (ret != -ENOTSUPP)
+               return ret;
 
        switch (mode) {
-       case PIN_CONFIG_BIAS_PULL_DOWN:
-       case PIN_CONFIG_BIAS_PULL_UP:
-               arg = 1;
+       case PIN_CONFIG_PERSIST_STATE:
+               dev_dbg(dev, "Persistence not supported for GPIO %d\n", gpio);
                break;
-
        default:
-               arg = 0;
+               break;
        }
 
-       config = PIN_CONF_PACKED(mode, arg);
-       return gpio_do_set_config(gc, gpio_chip_hwgpio(desc), config);
+       return 0;
+}
+
+static int gpio_set_config(struct gpio_desc *desc, enum pin_config_param mode)
+{
+       return gpio_set_config_with_argument(desc, mode, 0);
 }
 
 static int gpio_set_bias(struct gpio_desc *desc)
 {
-       int bias = 0;
-       int ret = 0;
+       enum pin_config_param bias;
+       unsigned int arg;
 
        if (test_bit(FLAG_BIAS_DISABLE, &desc->flags))
                bias = PIN_CONFIG_BIAS_DISABLE;
@@ -2282,13 +2153,28 @@ static int gpio_set_bias(struct gpio_desc *desc)
                bias = PIN_CONFIG_BIAS_PULL_UP;
        else if (test_bit(FLAG_PULL_DOWN, &desc->flags))
                bias = PIN_CONFIG_BIAS_PULL_DOWN;
+       else
+               return 0;
 
-       if (bias) {
-               ret = gpio_set_config(desc, bias);
-               if (ret != -ENOTSUPP)
-                       return ret;
+       switch (bias) {
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+       case PIN_CONFIG_BIAS_PULL_UP:
+               arg = 1;
+               break;
+
+       default:
+               arg = 0;
+               break;
        }
-       return 0;
+
+       return gpio_set_config_with_argument_optional(desc, bias, arg);
+}
+
+int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce)
+{
+       return gpio_set_config_with_argument_optional(desc,
+                                                     PIN_CONFIG_INPUT_DEBOUNCE,
+                                                     debounce);
 }
 
 /**
@@ -2510,7 +2396,7 @@ EXPORT_SYMBOL_GPL(gpiod_set_config);
  * 0 on success, %-ENOTSUPP if the controller doesn't support setting the
  * debounce time.
  */
-int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
+int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce)
 {
        unsigned long config;
 
@@ -2529,11 +2415,6 @@ EXPORT_SYMBOL_GPL(gpiod_set_debounce);
  */
 int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
 {
-       struct gpio_chip *gc;
-       unsigned long packed;
-       int gpio;
-       int rc;
-
        VALIDATE_DESC(desc);
        /*
         * Handle FLAG_TRANSITORY first, enabling queries to gpiolib for
@@ -2542,21 +2423,9 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
        assign_bit(FLAG_TRANSITORY, &desc->flags, transitory);
 
        /* If the driver supports it, set the persistence state now */
-       gc = desc->gdev->chip;
-       if (!gc->set_config)
-               return 0;
-
-       packed = pinconf_to_config_packed(PIN_CONFIG_PERSIST_STATE,
-                                         !transitory);
-       gpio = gpio_chip_hwgpio(desc);
-       rc = gpio_do_set_config(gc, gpio, packed);
-       if (rc == -ENOTSUPP) {
-               dev_dbg(&desc->gdev->dev, "Persistence not supported for GPIO %d\n",
-                               gpio);
-               return 0;
-       }
-
-       return rc;
+       return gpio_set_config_with_argument_optional(desc,
+                                                     PIN_CONFIG_PERSIST_STATE,
+                                                     !transitory);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_transitory);
 
@@ -3784,7 +3653,7 @@ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode,
 
                desc = fwnode_get_named_gpiod(fwnode, prop_name, index, flags,
                                              label);
-               if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
+               if (!gpiod_not_found(desc))
                        break;
        }
 
@@ -3960,7 +3829,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
         * Either we are not using DT or ACPI, or their lookup did not return
         * a result. In that case, use platform lookup as a fallback.
         */
-       if (!desc || desc == ERR_PTR(-ENOENT)) {
+       if (!desc || gpiod_not_found(desc)) {
                dev_dbg(dev, "using lookup tables for GPIO lookup\n");
                desc = gpiod_find(dev, con_id, idx, &lookupflags);
        }
@@ -3975,7 +3844,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
         * the device name as label
         */
        ret = gpiod_request(desc, con_id ? con_id : devname);
-       if (ret < 0) {
+       if (ret) {
                if (ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
                        /*
                         * This happens when there are several consumers for
@@ -4095,10 +3964,8 @@ struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
        struct gpio_desc *desc;
 
        desc = gpiod_get_index(dev, con_id, index, flags);
-       if (IS_ERR(desc)) {
-               if (PTR_ERR(desc) == -ENOENT)
-                       return NULL;
-       }
+       if (gpiod_not_found(desc))
+               return NULL;
 
        return desc;
 }
@@ -4300,7 +4167,7 @@ struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev,
        struct gpio_descs *descs;
 
        descs = gpiod_get_array(dev, con_id, flags);
-       if (PTR_ERR(descs) == -ENOENT)
+       if (gpiod_not_found(descs))
                return NULL;
 
        return descs;