Merge tag 'gpio-v4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[sfrench/cifs-2.6.git] / drivers / gpio / gpiolib.c
index 25187403e3ace0d891feaa3b59923efbcdb45a7a..230e41562462b27fdf5d11874b3de8c34c107707 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 #include <linux/bitmap.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -210,15 +211,15 @@ static int gpiochip_find_base(int ngpio)
  */
 int gpiod_get_direction(struct gpio_desc *desc)
 {
-       struct gpio_chip        *chip;
-       unsigned                offset;
-       int                     status = -EINVAL;
+       struct gpio_chip *chip;
+       unsigned offset;
+       int status;
 
        chip = gpiod_to_chip(desc);
        offset = gpio_chip_hwgpio(desc);
 
        if (!chip->get_direction)
-               return status;
+               return -ENOTSUPP;
 
        status = chip->get_direction(chip, offset);
        if (status > 0) {
@@ -359,7 +360,7 @@ static unsigned long *gpiochip_allocate_mask(struct gpio_chip *chip)
        return p;
 }
 
-static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
+static int gpiochip_alloc_valid_mask(struct gpio_chip *gpiochip)
 {
 #ifdef CONFIG_OF_GPIO
        int size;
@@ -380,6 +381,14 @@ static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
        return 0;
 }
 
+static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
+{
+       if (gpiochip->init_valid_mask)
+               return gpiochip->init_valid_mask(gpiochip);
+
+       return 0;
+}
+
 static void gpiochip_free_valid_mask(struct gpio_chip *gpiochip)
 {
        kfree(gpiochip->valid_mask);
@@ -427,7 +436,7 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
        struct linehandle_state *lh = filep->private_data;
        void __user *ip = (void __user *)arg;
        struct gpiohandle_data ghd;
-       int vals[GPIOHANDLES_MAX];
+       DECLARE_BITMAP(vals, GPIOHANDLES_MAX);
        int i;
 
        if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
@@ -436,13 +445,14 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
                                                        true,
                                                        lh->numdescs,
                                                        lh->descs,
+                                                       NULL,
                                                        vals);
                if (ret)
                        return ret;
 
                memset(&ghd, 0, sizeof(ghd));
                for (i = 0; i < lh->numdescs; i++)
-                       ghd.values[i] = vals[i];
+                       ghd.values[i] = test_bit(i, vals);
 
                if (copy_to_user(ip, &ghd, sizeof(ghd)))
                        return -EFAULT;
@@ -461,13 +471,14 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
 
                /* Clamp all values to [0,1] */
                for (i = 0; i < lh->numdescs; i++)
-                       vals[i] = !!ghd.values[i];
+                       __assign_bit(i, vals, ghd.values[i]);
 
                /* Reuse the array setting function */
                return gpiod_set_array_value_complex(false,
                                              true,
                                              lh->numdescs,
                                              lh->descs,
+                                             NULL,
                                              vals);
        }
        return -EINVAL;
@@ -812,26 +823,26 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
 {
        struct lineevent_state *le = p;
        struct gpioevent_data ge;
-       int ret, level;
+       int ret;
 
        /* Do not leak kernel stack to userspace */
        memset(&ge, 0, sizeof(ge));
 
        ge.timestamp = le->timestamp;
-       level = gpiod_get_value_cansleep(le->desc);
 
        if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE
            && le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
+               int level = gpiod_get_value_cansleep(le->desc);
                if (level)
                        /* Emit low-to-high event */
                        ge.id = GPIOEVENT_EVENT_RISING_EDGE;
                else
                        /* Emit high-to-low event */
                        ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
-       } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE && level) {
+       } else if (le->eflags & GPIOEVENT_REQUEST_RISING_EDGE) {
                /* Emit low-to-high event */
                ge.id = GPIOEVENT_EVENT_RISING_EDGE;
-       } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE && !level) {
+       } else if (le->eflags & GPIOEVENT_REQUEST_FALLING_EDGE) {
                /* Emit high-to-low event */
                ge.id = GPIOEVENT_EVENT_FALLING_EDGE;
        } else {
@@ -942,7 +953,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
        if (eflags & GPIOEVENT_REQUEST_FALLING_EDGE)
                irqflags |= IRQF_TRIGGER_FALLING;
        irqflags |= IRQF_ONESHOT;
-       irqflags |= IRQF_SHARED;
 
        INIT_KFIFO(le->events);
        init_waitqueue_head(&le->wait);
@@ -1341,19 +1351,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
 
        spin_unlock_irqrestore(&gpio_lock, flags);
 
-       for (i = 0; i < chip->ngpio; i++) {
-               struct gpio_desc *desc = &gdev->descs[i];
-
-               desc->gdev = gdev;
-
-               /* REVISIT: most hardware initializes GPIOs as inputs (often
-                * with pullups enabled) so power usage is minimized. Linux
-                * code should set the gpio direction first thing; but until
-                * it does, and in case chip->get_direction is not set, we may
-                * expose the wrong direction in sysfs.
-                */
-               desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0;
-       }
+       for (i = 0; i < chip->ngpio; i++)
+               gdev->descs[i].gdev = gdev;
 
 #ifdef CONFIG_PINCTRL
        INIT_LIST_HEAD(&gdev->pin_ranges);
@@ -1367,7 +1366,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        if (status)
                goto err_remove_from_list;
 
-       status = gpiochip_init_valid_mask(chip);
+       status = gpiochip_alloc_valid_mask(chip);
        if (status)
                goto err_remove_irqchip_mask;
 
@@ -1379,6 +1378,21 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        if (status)
                goto err_remove_chip;
 
+       status = gpiochip_init_valid_mask(chip);
+       if (status)
+               goto err_remove_chip;
+
+       for (i = 0; i < chip->ngpio; i++) {
+               struct gpio_desc *desc = &gdev->descs[i];
+
+               if (chip->get_direction && gpiochip_line_is_valid(chip, i))
+                       desc->flags = !chip->get_direction(chip, i) ?
+                                       (1 << FLAG_IS_OUT) : 0;
+               else
+                       desc->flags = !chip->direction_input ?
+                                       (1 << FLAG_IS_OUT) : 0;
+       }
+
        acpi_gpiochip_add(chip);
 
        machine_gpiochip_add(chip);
@@ -1512,7 +1526,7 @@ static int devm_gpio_chip_match(struct device *dev, void *res, void *data)
 
 /**
  * devm_gpiochip_add_data() - Resource manager gpiochip_add_data()
- * @dev: the device pointer on which irq_chip belongs to.
+ * @dev: pointer to the device that gpio_chip belongs to.
  * @chip: the chip to register, with chip->base initialized
  * @data: driver-private data associated with this chip
  *
@@ -1649,7 +1663,6 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_irq_valid);
 /**
  * gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip
  * @gpiochip: the gpiochip to set the irqchip chain to
- * @irqchip: the irqchip to chain to the gpiochip
  * @parent_irq: the irq number corresponding to the parent IRQ for this
  * chained irqchip
  * @parent_handler: the parent interrupt handler for the accumulated IRQ
@@ -1657,12 +1670,9 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_irq_valid);
  * cascaded, pass NULL in this handler argument
  */
 static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip,
-                                         struct irq_chip *irqchip,
                                          unsigned int parent_irq,
                                          irq_flow_handler_t parent_handler)
 {
-       unsigned int offset;
-
        if (!gpiochip->irq.domain) {
                chip_err(gpiochip, "called %s before setting up irqchip\n",
                         __func__);
@@ -1686,14 +1696,6 @@ static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip,
                gpiochip->irq.parents = &gpiochip->irq.parent_irq;
                gpiochip->irq.num_parents = 1;
        }
-
-       /* Set the parent IRQ for all affected IRQs */
-       for (offset = 0; offset < gpiochip->ngpio; offset++) {
-               if (!gpiochip_irqchip_irq_valid(gpiochip, offset))
-                       continue;
-               irq_set_parent(irq_find_mapping(gpiochip->irq.domain, offset),
-                              parent_irq);
-       }
 }
 
 /**
@@ -1703,8 +1705,7 @@ static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip,
  * @parent_irq: the irq number corresponding to the parent IRQ for this
  * chained 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
+ * coming out of the gpiochip.
  */
 void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
                                  struct irq_chip *irqchip,
@@ -1716,8 +1717,7 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
                return;
        }
 
-       gpiochip_set_cascaded_irqchip(gpiochip, irqchip, parent_irq,
-                                     parent_handler);
+       gpiochip_set_cascaded_irqchip(gpiochip, parent_irq, parent_handler);
 }
 EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip);
 
@@ -1732,8 +1732,7 @@ void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip,
                                 struct irq_chip *irqchip,
                                 unsigned int parent_irq)
 {
-       gpiochip_set_cascaded_irqchip(gpiochip, irqchip, parent_irq,
-                                     NULL);
+       gpiochip_set_cascaded_irqchip(gpiochip, parent_irq, NULL);
 }
 EXPORT_SYMBOL_GPL(gpiochip_set_nested_irqchip);
 
@@ -1805,39 +1804,75 @@ static const struct irq_domain_ops gpiochip_domain_ops = {
        .xlate  = irq_domain_xlate_twocell,
 };
 
+static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       if (!gpiochip_irqchip_irq_valid(chip, offset))
+               return -ENXIO;
+
+       return irq_create_mapping(chip->irq.domain, offset);
+}
+
 static int gpiochip_irq_reqres(struct irq_data *d)
 {
        struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
-       int ret;
-
-       if (!try_module_get(chip->gpiodev->owner))
-               return -ENODEV;
 
-       ret = gpiochip_lock_as_irq(chip, d->hwirq);
-       if (ret) {
-               chip_err(chip,
-                       "unable to lock HW IRQ %lu for IRQ\n",
-                       d->hwirq);
-               module_put(chip->gpiodev->owner);
-               return ret;
-       }
-       return 0;
+       return gpiochip_reqres_irq(chip, d->hwirq);
 }
 
 static void gpiochip_irq_relres(struct irq_data *d)
 {
        struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
 
-       gpiochip_unlock_as_irq(chip, d->hwirq);
-       module_put(chip->gpiodev->owner);
+       gpiochip_relres_irq(chip, d->hwirq);
 }
 
-static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset)
+static void gpiochip_irq_enable(struct irq_data *d)
 {
-       if (!gpiochip_irqchip_irq_valid(chip, offset))
-               return -ENXIO;
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
 
-       return irq_create_mapping(chip->irq.domain, offset);
+       gpiochip_enable_irq(chip, d->hwirq);
+       if (chip->irq.irq_enable)
+               chip->irq.irq_enable(d);
+       else
+               chip->irq.chip->irq_unmask(d);
+}
+
+static void gpiochip_irq_disable(struct irq_data *d)
+{
+       struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+
+       if (chip->irq.irq_disable)
+               chip->irq.irq_disable(d);
+       else
+               chip->irq.chip->irq_mask(d);
+       gpiochip_disable_irq(chip, d->hwirq);
+}
+
+static void gpiochip_set_irq_hooks(struct gpio_chip *gpiochip)
+{
+       struct irq_chip *irqchip = gpiochip->irq.chip;
+
+       if (!irqchip->irq_request_resources &&
+           !irqchip->irq_release_resources) {
+               irqchip->irq_request_resources = gpiochip_irq_reqres;
+               irqchip->irq_release_resources = gpiochip_irq_relres;
+       }
+       if (WARN_ON(gpiochip->irq.irq_enable))
+               return;
+       /* Check if the irqchip already has this hook... */
+       if (irqchip->irq_enable == gpiochip_irq_enable) {
+               /*
+                * ...and if so, give a gentle warning that this is bad
+                * practice.
+                */
+               chip_info(gpiochip,
+                         "detected irqchip that is shared with multiple gpiochips: please fix the driver.\n");
+               return;
+       }
+       gpiochip->irq.irq_enable = irqchip->irq_enable;
+       gpiochip->irq.irq_disable = irqchip->irq_disable;
+       irqchip->irq_enable = gpiochip_irq_enable;
+       irqchip->irq_disable = gpiochip_irq_disable;
 }
 
 /**
@@ -1898,16 +1933,6 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
        if (!gpiochip->irq.domain)
                return -EINVAL;
 
-       /*
-        * It is possible for a driver to override this, but only if the
-        * alternative functions are both implemented.
-        */
-       if (!irqchip->irq_request_resources &&
-           !irqchip->irq_release_resources) {
-               irqchip->irq_request_resources = gpiochip_irq_reqres;
-               irqchip->irq_release_resources = gpiochip_irq_relres;
-       }
-
        if (gpiochip->irq.parent_handler) {
                void *data = gpiochip->irq.parent_handler_data ?: gpiochip;
 
@@ -1923,6 +1948,8 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
                }
        }
 
+       gpiochip_set_irq_hooks(gpiochip);
+
        acpi_gpiochip_request_interrupts(gpiochip);
 
        return 0;
@@ -1936,11 +1963,12 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
  */
 static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
 {
+       struct irq_chip *irqchip = gpiochip->irq.chip;
        unsigned int offset;
 
        acpi_gpiochip_free_interrupts(gpiochip);
 
-       if (gpiochip->irq.chip && gpiochip->irq.parent_handler) {
+       if (irqchip && gpiochip->irq.parent_handler) {
                struct gpio_irq_chip *irq = &gpiochip->irq;
                unsigned int i;
 
@@ -1964,11 +1992,19 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
                irq_domain_remove(gpiochip->irq.domain);
        }
 
-       if (gpiochip->irq.chip) {
-               gpiochip->irq.chip->irq_request_resources = NULL;
-               gpiochip->irq.chip->irq_release_resources = NULL;
-               gpiochip->irq.chip = NULL;
+       if (irqchip) {
+               if (irqchip->irq_request_resources == gpiochip_irq_reqres) {
+                       irqchip->irq_request_resources = NULL;
+                       irqchip->irq_release_resources = NULL;
+               }
+               if (irqchip->irq_enable == gpiochip_irq_enable) {
+                       irqchip->irq_enable = gpiochip->irq.irq_enable;
+                       irqchip->irq_disable = gpiochip->irq.irq_disable;
+               }
        }
+       gpiochip->irq.irq_enable = NULL;
+       gpiochip->irq.irq_disable = NULL;
+       gpiochip->irq.chip = NULL;
 
        gpiochip_irqchip_free_valid_mask(gpiochip);
 }
@@ -2057,15 +2093,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
                return -EINVAL;
        }
 
-       /*
-        * It is possible for a driver to override this, but only if the
-        * alternative functions are both implemented.
-        */
-       if (!irqchip->irq_request_resources &&
-           !irqchip->irq_release_resources) {
-               irqchip->irq_request_resources = gpiochip_irq_reqres;
-               irqchip->irq_release_resources = gpiochip_irq_relres;
-       }
+       gpiochip_set_irq_hooks(gpiochip);
 
        acpi_gpiochip_request_interrupts(gpiochip);
 
@@ -2513,19 +2541,38 @@ EXPORT_SYMBOL_GPL(gpiochip_free_own_desc);
 int gpiod_direction_input(struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
-       int                     status = -EINVAL;
+       int                     status = 0;
 
        VALIDATE_DESC(desc);
        chip = desc->gdev->chip;
 
-       if (!chip->get || !chip->direction_input) {
+       /*
+        * It is legal to have no .get() and .direction_input() specified if
+        * the chip is output-only, but you can't specify .direction_input()
+        * and not support the .get() operation, that doesn't make sense.
+        */
+       if (!chip->get && chip->direction_input) {
                gpiod_warn(desc,
-                       "%s: missing get() or direction_input() operations\n",
-                       __func__);
+                          "%s: missing get() but have direction_input()\n",
+                          __func__);
                return -EIO;
        }
 
-       status = chip->direction_input(chip, gpio_chip_hwgpio(desc));
+       /*
+        * If we have a .direction_input() callback, things are simple,
+        * just call it. Else we are some input-only chip so try to check the
+        * direction (if .get_direction() is supported) else we silently
+        * assume we are in input mode after this.
+        */
+       if (chip->direction_input) {
+               status = chip->direction_input(chip, gpio_chip_hwgpio(desc));
+       } else if (chip->get_direction &&
+                 (chip->get_direction(chip, gpio_chip_hwgpio(desc)) != 1)) {
+               gpiod_warn(desc,
+                          "%s: missing direction_input() operation and line is output\n",
+                          __func__);
+               return -EIO;
+       }
        if (status == 0)
                clear_bit(FLAG_IS_OUT, &desc->flags);
 
@@ -2547,16 +2594,38 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value)
 {
        struct gpio_chip *gc = desc->gdev->chip;
        int val = !!value;
-       int ret;
+       int ret = 0;
 
-       if (!gc->set || !gc->direction_output) {
+       /*
+        * It's OK not to specify .direction_output() if the gpiochip is
+        * output-only, but if there is then not even a .set() operation it
+        * is pretty tricky to drive the output line.
+        */
+       if (!gc->set && !gc->direction_output) {
                gpiod_warn(desc,
-                      "%s: missing set() or direction_output() operations\n",
-                      __func__);
+                          "%s: missing set() and direction_output() operations\n",
+                          __func__);
                return -EIO;
        }
 
-       ret = gc->direction_output(gc, gpio_chip_hwgpio(desc), val);
+       if (gc->direction_output) {
+               ret = gc->direction_output(gc, gpio_chip_hwgpio(desc), val);
+       } else {
+               /* Check that we are in output mode if we can */
+               if (gc->get_direction &&
+                   gc->get_direction(gc, gpio_chip_hwgpio(desc))) {
+                       gpiod_warn(desc,
+                               "%s: missing direction_output() operation\n",
+                               __func__);
+                       return -EIO;
+               }
+               /*
+                * If we can't actively set the direction, we are some
+                * output-only chip, so just drive the output as desired.
+                */
+               gc->set(gc, gpio_chip_hwgpio(desc), val);
+       }
+
        if (!ret)
                set_bit(FLAG_IS_OUT, &desc->flags);
        trace_gpio_value(desc_to_gpio(desc), 0, val);
@@ -2605,8 +2674,9 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
        else
                value = !!value;
 
-       /* GPIOs used for IRQs shall not be set as output */
-       if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) {
+       /* GPIOs used for enabled IRQs shall not be set as output */
+       if (test_bit(FLAG_USED_AS_IRQ, &desc->flags) &&
+           test_bit(FLAG_IRQ_IS_ENABLED, &desc->flags)) {
                gpiod_err(desc,
                          "%s: tried to set a GPIO tied to an IRQ as output\n",
                          __func__);
@@ -2785,9 +2855,39 @@ static int gpio_chip_get_multiple(struct gpio_chip *chip,
 int gpiod_get_array_value_complex(bool raw, bool can_sleep,
                                  unsigned int array_size,
                                  struct gpio_desc **desc_array,
-                                 int *value_array)
+                                 struct gpio_array *array_info,
+                                 unsigned long *value_bitmap)
 {
-       int i = 0;
+       int err, i = 0;
+
+       /*
+        * Validate array_info against desc_array and its size.
+        * It should immediately follow desc_array if both
+        * have been obtained from the same gpiod_get_array() call.
+        */
+       if (array_info && array_info->desc == desc_array &&
+           array_size <= array_info->size &&
+           (void *)array_info == desc_array + array_info->size) {
+               if (!can_sleep)
+                       WARN_ON(array_info->chip->can_sleep);
+
+               err = gpio_chip_get_multiple(array_info->chip,
+                                            array_info->get_mask,
+                                            value_bitmap);
+               if (err)
+                       return err;
+
+               if (!raw && !bitmap_empty(array_info->invert_mask, array_size))
+                       bitmap_xor(value_bitmap, value_bitmap,
+                                  array_info->invert_mask, array_size);
+
+               if (bitmap_full(array_info->get_mask, array_size))
+                       return 0;
+
+               i = find_first_zero_bit(array_info->get_mask, array_size);
+       } else {
+               array_info = NULL;
+       }
 
        while (i < array_size) {
                struct gpio_chip *chip = desc_array[i]->gdev->chip;
@@ -2819,6 +2919,10 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
 
                        __set_bit(hwgpio, mask);
                        i++;
+
+                       if (array_info)
+                               i = find_next_zero_bit(array_info->get_mask,
+                                                      array_size, i);
                } while ((i < array_size) &&
                         (desc_array[i]->gdev->chip == chip));
 
@@ -2829,15 +2933,20 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
                        return ret;
                }
 
-               for (j = first; j < i; j++) {
+               for (j = first; j < i; ) {
                        const struct gpio_desc *desc = desc_array[j];
                        int hwgpio = gpio_chip_hwgpio(desc);
                        int value = test_bit(hwgpio, bits);
 
                        if (!raw && test_bit(FLAG_ACTIVE_LOW, &desc->flags))
                                value = !value;
-                       value_array[j] = value;
+                       __assign_bit(j, value_bitmap, value);
                        trace_gpio_value(desc_to_gpio(desc), 1, value);
+                       j++;
+
+                       if (array_info)
+                               j = find_next_zero_bit(array_info->get_mask, i,
+                                                      j);
                }
 
                if (mask != fastpath)
@@ -2896,9 +3005,10 @@ EXPORT_SYMBOL_GPL(gpiod_get_value);
 
 /**
  * gpiod_get_raw_array_value() - read raw values from an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be read
- * @value_array: array to store the read values
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap to store the read values
  *
  * Read the raw values of the GPIOs, i.e. the values of the physical lines
  * without regard for their ACTIVE_LOW status.  Return 0 in case of success,
@@ -2908,20 +3018,24 @@ EXPORT_SYMBOL_GPL(gpiod_get_value);
  * and it will complain if the GPIO chip functions potentially sleep.
  */
 int gpiod_get_raw_array_value(unsigned int array_size,
-                             struct gpio_desc **desc_array, int *value_array)
+                             struct gpio_desc **desc_array,
+                             struct gpio_array *array_info,
+                             unsigned long *value_bitmap)
 {
        if (!desc_array)
                return -EINVAL;
        return gpiod_get_array_value_complex(true, false, array_size,
-                                            desc_array, value_array);
+                                            desc_array, array_info,
+                                            value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
 
 /**
  * gpiod_get_array_value() - read values from an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be read
- * @value_array: array to store the read values
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap to store the read values
  *
  * Read the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
  * into account.  Return 0 in case of success, else an error code.
@@ -2930,12 +3044,15 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value);
  * and it will complain if the GPIO chip functions potentially sleep.
  */
 int gpiod_get_array_value(unsigned int array_size,
-                         struct gpio_desc **desc_array, int *value_array)
+                         struct gpio_desc **desc_array,
+                         struct gpio_array *array_info,
+                         unsigned long *value_bitmap)
 {
        if (!desc_array)
                return -EINVAL;
        return gpiod_get_array_value_complex(false, false, array_size,
-                                            desc_array, value_array);
+                                            desc_array, array_info,
+                                            value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_array_value);
 
@@ -3026,12 +3143,39 @@ static void gpio_chip_set_multiple(struct gpio_chip *chip,
 }
 
 int gpiod_set_array_value_complex(bool raw, bool can_sleep,
-                                  unsigned int array_size,
-                                  struct gpio_desc **desc_array,
-                                  int *value_array)
+                                 unsigned int array_size,
+                                 struct gpio_desc **desc_array,
+                                 struct gpio_array *array_info,
+                                 unsigned long *value_bitmap)
 {
        int i = 0;
 
+       /*
+        * Validate array_info against desc_array and its size.
+        * It should immediately follow desc_array if both
+        * have been obtained from the same gpiod_get_array() call.
+        */
+       if (array_info && array_info->desc == desc_array &&
+           array_size <= array_info->size &&
+           (void *)array_info == desc_array + array_info->size) {
+               if (!can_sleep)
+                       WARN_ON(array_info->chip->can_sleep);
+
+               if (!raw && !bitmap_empty(array_info->invert_mask, array_size))
+                       bitmap_xor(value_bitmap, value_bitmap,
+                                  array_info->invert_mask, array_size);
+
+               gpio_chip_set_multiple(array_info->chip, array_info->set_mask,
+                                      value_bitmap);
+
+               if (bitmap_full(array_info->set_mask, array_size))
+                       return 0;
+
+               i = find_first_zero_bit(array_info->set_mask, array_size);
+       } else {
+               array_info = NULL;
+       }
+
        while (i < array_size) {
                struct gpio_chip *chip = desc_array[i]->gdev->chip;
                unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)];
@@ -3057,9 +3201,16 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
                do {
                        struct gpio_desc *desc = desc_array[i];
                        int hwgpio = gpio_chip_hwgpio(desc);
-                       int value = value_array[i];
+                       int value = test_bit(i, value_bitmap);
 
-                       if (!raw && test_bit(FLAG_ACTIVE_LOW, &desc->flags))
+                       /*
+                        * Pins applicable for fast input but not for
+                        * fast output processing may have been already
+                        * inverted inside the fast path, skip them.
+                        */
+                       if (!raw && !(array_info &&
+                           test_bit(i, array_info->invert_mask)) &&
+                           test_bit(FLAG_ACTIVE_LOW, &desc->flags))
                                value = !value;
                        trace_gpio_value(desc_to_gpio(desc), 0, value);
                        /*
@@ -3079,6 +3230,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,
                                count++;
                        }
                        i++;
+
+                       if (array_info)
+                               i = find_next_zero_bit(array_info->set_mask,
+                                                      array_size, i);
                } while ((i < array_size) &&
                         (desc_array[i]->gdev->chip == chip));
                /* push collected bits to outputs */
@@ -3153,9 +3308,10 @@ EXPORT_SYMBOL_GPL(gpiod_set_value);
 
 /**
  * gpiod_set_raw_array_value() - assign values to an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be assigned
- * @value_array: array of values to assign
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap of values to assign
  *
  * Set the raw values of the GPIOs, i.e. the values of the physical lines
  * without regard for their ACTIVE_LOW status.
@@ -3164,20 +3320,23 @@ EXPORT_SYMBOL_GPL(gpiod_set_value);
  * complain if the GPIO chip functions potentially sleep.
  */
 int gpiod_set_raw_array_value(unsigned int array_size,
-                        struct gpio_desc **desc_array, int *value_array)
+                             struct gpio_desc **desc_array,
+                             struct gpio_array *array_info,
+                             unsigned long *value_bitmap)
 {
        if (!desc_array)
                return -EINVAL;
        return gpiod_set_array_value_complex(true, false, array_size,
-                                       desc_array, value_array);
+                                       desc_array, array_info, value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value);
 
 /**
  * gpiod_set_array_value() - assign values to an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be assigned
- * @value_array: array of values to assign
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap of values to assign
  *
  * Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
  * into account.
@@ -3185,13 +3344,16 @@ EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value);
  * This function should be called from contexts where we cannot sleep, and will
  * complain if the GPIO chip functions potentially sleep.
  */
-void gpiod_set_array_value(unsigned int array_size,
-                          struct gpio_desc **desc_array, int *value_array)
+int gpiod_set_array_value(unsigned int array_size,
+                         struct gpio_desc **desc_array,
+                         struct gpio_array *array_info,
+                         unsigned long *value_bitmap)
 {
        if (!desc_array)
-               return;
-       gpiod_set_array_value_complex(false, false, array_size, desc_array,
-                                     value_array);
+               return -EINVAL;
+       return gpiod_set_array_value_complex(false, false, array_size,
+                                            desc_array, array_info,
+                                            value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_array_value);
 
@@ -3293,6 +3455,7 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
        }
 
        set_bit(FLAG_USED_AS_IRQ, &desc->flags);
+       set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
 
        /*
         * If the consumer has not set up a label (such as when the
@@ -3323,6 +3486,7 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
                return;
 
        clear_bit(FLAG_USED_AS_IRQ, &desc->flags);
+       clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
 
        /* If we only had this marking, erase it */
        if (desc->label && !strcmp(desc->label, "interrupt"))
@@ -3330,6 +3494,28 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
 }
 EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq);
 
+void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       struct gpio_desc *desc = gpiochip_get_desc(chip, offset);
+
+       if (!IS_ERR(desc) &&
+           !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags)))
+               clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
+}
+EXPORT_SYMBOL_GPL(gpiochip_disable_irq);
+
+void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       struct gpio_desc *desc = gpiochip_get_desc(chip, offset);
+
+       if (!IS_ERR(desc) &&
+           !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags))) {
+               WARN_ON(test_bit(FLAG_IS_OUT, &desc->flags));
+               set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags);
+       }
+}
+EXPORT_SYMBOL_GPL(gpiochip_enable_irq);
+
 bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset)
 {
        if (offset >= chip->ngpio)
@@ -3339,6 +3525,30 @@ bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset)
 }
 EXPORT_SYMBOL_GPL(gpiochip_line_is_irq);
 
+int gpiochip_reqres_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       int ret;
+
+       if (!try_module_get(chip->gpiodev->owner))
+               return -ENODEV;
+
+       ret = gpiochip_lock_as_irq(chip, offset);
+       if (ret) {
+               chip_err(chip, "unable to lock HW IRQ %u for IRQ\n", offset);
+               module_put(chip->gpiodev->owner);
+               return ret;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gpiochip_reqres_irq);
+
+void gpiochip_relres_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       gpiochip_unlock_as_irq(chip, offset);
+       module_put(chip->gpiodev->owner);
+}
+EXPORT_SYMBOL_GPL(gpiochip_relres_irq);
+
 bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset)
 {
        if (offset >= chip->ngpio)
@@ -3411,9 +3621,10 @@ EXPORT_SYMBOL_GPL(gpiod_get_value_cansleep);
 
 /**
  * gpiod_get_raw_array_value_cansleep() - read raw values from an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be read
- * @value_array: array to store the read values
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap to store the read values
  *
  * Read the raw values of the GPIOs, i.e. the values of the physical lines
  * without regard for their ACTIVE_LOW status.  Return 0 in case of success,
@@ -3423,21 +3634,24 @@ EXPORT_SYMBOL_GPL(gpiod_get_value_cansleep);
  */
 int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
                                       struct gpio_desc **desc_array,
-                                      int *value_array)
+                                      struct gpio_array *array_info,
+                                      unsigned long *value_bitmap)
 {
        might_sleep_if(extra_checks);
        if (!desc_array)
                return -EINVAL;
        return gpiod_get_array_value_complex(true, true, array_size,
-                                            desc_array, value_array);
+                                            desc_array, array_info,
+                                            value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value_cansleep);
 
 /**
  * gpiod_get_array_value_cansleep() - read values from an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be read
- * @value_array: array to store the read values
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap to store the read values
  *
  * Read the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
  * into account.  Return 0 in case of success, else an error code.
@@ -3446,13 +3660,15 @@ EXPORT_SYMBOL_GPL(gpiod_get_raw_array_value_cansleep);
  */
 int gpiod_get_array_value_cansleep(unsigned int array_size,
                                   struct gpio_desc **desc_array,
-                                  int *value_array)
+                                  struct gpio_array *array_info,
+                                  unsigned long *value_bitmap)
 {
        might_sleep_if(extra_checks);
        if (!desc_array)
                return -EINVAL;
        return gpiod_get_array_value_complex(false, true, array_size,
-                                            desc_array, value_array);
+                                            desc_array, array_info,
+                                            value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_get_array_value_cansleep);
 
@@ -3494,9 +3710,10 @@ EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep);
 
 /**
  * gpiod_set_raw_array_value_cansleep() - assign values to an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be assigned
- * @value_array: array of values to assign
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap of values to assign
  *
  * Set the raw values of the GPIOs, i.e. the values of the physical lines
  * without regard for their ACTIVE_LOW status.
@@ -3504,14 +3721,15 @@ EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep);
  * This function is to be called from contexts that can sleep.
  */
 int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
-                                       struct gpio_desc **desc_array,
-                                       int *value_array)
+                                      struct gpio_desc **desc_array,
+                                      struct gpio_array *array_info,
+                                      unsigned long *value_bitmap)
 {
        might_sleep_if(extra_checks);
        if (!desc_array)
                return -EINVAL;
        return gpiod_set_array_value_complex(true, true, array_size, desc_array,
-                                     value_array);
+                                     array_info, value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_raw_array_value_cansleep);
 
@@ -3534,24 +3752,27 @@ void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n)
 
 /**
  * gpiod_set_array_value_cansleep() - assign values to an array of GPIOs
- * @array_size: number of elements in the descriptor / value arrays
+ * @array_size: number of elements in the descriptor array / value bitmap
  * @desc_array: array of GPIO descriptors whose values will be assigned
- * @value_array: array of values to assign
+ * @array_info: information on applicability of fast bitmap processing path
+ * @value_bitmap: bitmap of values to assign
  *
  * Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
  * into account.
  *
  * This function is to be called from contexts that can sleep.
  */
-void gpiod_set_array_value_cansleep(unsigned int array_size,
-                                   struct gpio_desc **desc_array,
-                                   int *value_array)
+int gpiod_set_array_value_cansleep(unsigned int array_size,
+                                  struct gpio_desc **desc_array,
+                                  struct gpio_array *array_info,
+                                  unsigned long *value_bitmap)
 {
        might_sleep_if(extra_checks);
        if (!desc_array)
-               return;
-       gpiod_set_array_value_complex(false, true, array_size, desc_array,
-                                     value_array);
+               return -EINVAL;
+       return gpiod_set_array_value_complex(false, true, array_size,
+                                            desc_array, array_info,
+                                            value_bitmap);
 }
 EXPORT_SYMBOL_GPL(gpiod_set_array_value_cansleep);
 
@@ -3909,8 +4130,23 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
         * the device name as label
         */
        status = gpiod_request(desc, con_id ? con_id : devname);
-       if (status < 0)
-               return ERR_PTR(status);
+       if (status < 0) {
+               if (status == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
+                       /*
+                        * This happens when there are several consumers for
+                        * the same GPIO line: we just return here without
+                        * further initialization. It is a bit if a hack.
+                        * This is necessary to support fixed regulators.
+                        *
+                        * FIXME: Make this more sane and safe.
+                        */
+                       dev_info(dev, "nonexclusive access to GPIO for %s\n",
+                                con_id ? con_id : devname);
+                       return desc;
+               } else {
+                       return ERR_PTR(status);
+               }
+       }
 
        status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
        if (status < 0) {
@@ -4171,7 +4407,9 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
 {
        struct gpio_desc *desc;
        struct gpio_descs *descs;
-       int count;
+       struct gpio_array *array_info = NULL;
+       struct gpio_chip *chip;
+       int count, bitmap_size;
 
        count = gpiod_count(dev, con_id);
        if (count < 0)
@@ -4187,9 +4425,92 @@ struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
                        gpiod_put_array(descs);
                        return ERR_CAST(desc);
                }
+
                descs->desc[descs->ndescs] = desc;
+
+               chip = gpiod_to_chip(desc);
+               /*
+                * If pin hardware number of array member 0 is also 0, select
+                * its chip as a candidate for fast bitmap processing path.
+                */
+               if (descs->ndescs == 0 && gpio_chip_hwgpio(desc) == 0) {
+                       struct gpio_descs *array;
+
+                       bitmap_size = BITS_TO_LONGS(chip->ngpio > count ?
+                                                   chip->ngpio : count);
+
+                       array = kzalloc(struct_size(descs, desc, count) +
+                                       struct_size(array_info, invert_mask,
+                                       3 * bitmap_size), GFP_KERNEL);
+                       if (!array) {
+                               gpiod_put_array(descs);
+                               return ERR_PTR(-ENOMEM);
+                       }
+
+                       memcpy(array, descs,
+                              struct_size(descs, desc, descs->ndescs + 1));
+                       kfree(descs);
+
+                       descs = array;
+                       array_info = (void *)(descs->desc + count);
+                       array_info->get_mask = array_info->invert_mask +
+                                                 bitmap_size;
+                       array_info->set_mask = array_info->get_mask +
+                                                 bitmap_size;
+
+                       array_info->desc = descs->desc;
+                       array_info->size = count;
+                       array_info->chip = chip;
+                       bitmap_set(array_info->get_mask, descs->ndescs,
+                                  count - descs->ndescs);
+                       bitmap_set(array_info->set_mask, descs->ndescs,
+                                  count - descs->ndescs);
+                       descs->info = array_info;
+               }
+               /* Unmark array members which don't belong to the 'fast' chip */
+               if (array_info && array_info->chip != chip) {
+                       __clear_bit(descs->ndescs, array_info->get_mask);
+                       __clear_bit(descs->ndescs, array_info->set_mask);
+               }
+               /*
+                * Detect array members which belong to the 'fast' chip
+                * but their pins are not in hardware order.
+                */
+               else if (array_info &&
+                          gpio_chip_hwgpio(desc) != descs->ndescs) {
+                       /*
+                        * Don't use fast path if all array members processed so
+                        * far belong to the same chip as this one but its pin
+                        * hardware number is different from its array index.
+                        */
+                       if (bitmap_full(array_info->get_mask, descs->ndescs)) {
+                               array_info = NULL;
+                       } else {
+                               __clear_bit(descs->ndescs,
+                                           array_info->get_mask);
+                               __clear_bit(descs->ndescs,
+                                           array_info->set_mask);
+                       }
+               } else if (array_info) {
+                       /* Exclude open drain or open source from fast output */
+                       if (gpiochip_line_is_open_drain(chip, descs->ndescs) ||
+                           gpiochip_line_is_open_source(chip, descs->ndescs))
+                               __clear_bit(descs->ndescs,
+                                           array_info->set_mask);
+                       /* Identify 'fast' pins which require invertion */
+                       if (gpiod_is_active_low(desc))
+                               __set_bit(descs->ndescs,
+                                         array_info->invert_mask);
+               }
+
                descs->ndescs++;
        }
+       if (array_info)
+               dev_dbg(dev,
+                       "GPIO array info: chip=%s, size=%d, get_mask=%lx, set_mask=%lx, invert_mask=%lx\n",
+                       array_info->chip->label, array_info->size,
+                       *array_info->get_mask, *array_info->set_mask,
+                       *array_info->invert_mask);
        return descs;
 }
 EXPORT_SYMBOL_GPL(gpiod_get_array);
@@ -4276,8 +4597,9 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)
        struct gpio_chip        *chip = gdev->chip;
        unsigned                gpio = gdev->base;
        struct gpio_desc        *gdesc = &gdev->descs[0];
-       int                     is_out;
-       int                     is_irq;
+       bool                    is_out;
+       bool                    is_irq;
+       bool                    active_low;
 
        for (i = 0; i < gdev->ngpio; i++, gpio++, gdesc++) {
                if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) {
@@ -4291,11 +4613,13 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)
                gpiod_get_direction(gdesc);
                is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
                is_irq = test_bit(FLAG_USED_AS_IRQ, &gdesc->flags);
-               seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s",
+               active_low = test_bit(FLAG_ACTIVE_LOW, &gdesc->flags);
+               seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s%s",
                        gpio, gdesc->name ? gdesc->name : "", gdesc->label,
                        is_out ? "out" : "in ",
                        chip->get ? (chip->get(chip, i) ? "hi" : "lo") : "?  ",
-                       is_irq ? "IRQ" : "   ");
+                       is_irq ? "IRQ " : "",
+                       active_low ? "ACTIVE LOW" : "");
                seq_printf(s, "\n");
        }
 }