gpio: move sysfs support to its own file
[firefly-linux-kernel-4.4.55.git] / drivers / gpio / gpiolib.c
index f48817d974802c3ec771814bef84bc97ab6039b5..7b35e5093ef581bf55145aa9a191b9f52947560b 100644 (file)
  * While any GPIO is requested, its gpio_chip is not removable;
  * each GPIO's "requested" flag serves as a lock and refcount.
  */
-static DEFINE_SPINLOCK(gpio_lock);
+DEFINE_SPINLOCK(gpio_lock);
 
-struct gpio_desc {
-       struct gpio_chip        *chip;
-       unsigned long           flags;
-/* flag symbols are bit numbers */
-#define FLAG_REQUESTED 0
-#define FLAG_IS_OUT    1
-#define FLAG_EXPORT    2       /* protected by sysfs_lock */
-#define FLAG_SYSFS     3       /* exported via /sys/class/gpio/control */
-#define FLAG_TRIG_FALL 4       /* trigger on falling edge */
-#define FLAG_TRIG_RISE 5       /* trigger on rising edge */
-#define FLAG_ACTIVE_LOW        6       /* value has active low */
-#define FLAG_OPEN_DRAIN        7       /* Gpio is open drain type */
-#define FLAG_OPEN_SOURCE 8     /* Gpio is open source type */
-#define FLAG_USED_AS_IRQ 9     /* GPIO is connected to an IRQ */
-
-#define ID_SHIFT       16      /* add new flags before this one */
-
-#define GPIO_FLAGS_MASK                ((1 << ID_SHIFT) - 1)
-#define GPIO_TRIGGER_MASK      (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE))
-
-#ifdef CONFIG_DEBUG_FS
-       const char              *label;
-#endif
-};
 static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
 
 #define GPIO_OFFSET_VALID(chip, offset) (offset >= 0 && offset < chip->ngpio)
 
 static DEFINE_MUTEX(gpio_lookup_lock);
 static LIST_HEAD(gpio_lookup_list);
-static LIST_HEAD(gpio_chips);
-
-#ifdef CONFIG_GPIO_SYSFS
-static DEFINE_IDR(dirent_idr);
-#endif
-
-static int gpiod_request(struct gpio_desc *desc, const char *label);
-static void gpiod_free(struct gpio_desc *desc);
-
-/* With descriptor prefix */
-
-#ifdef CONFIG_DEBUG_FS
-#define gpiod_emerg(desc, fmt, ...)                                           \
-       pr_emerg("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\
-                 ##__VA_ARGS__)
-#define gpiod_crit(desc, fmt, ...)                                            \
-       pr_crit("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
-                 ##__VA_ARGS__)
-#define gpiod_err(desc, fmt, ...)                                             \
-       pr_err("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",  \
-                 ##__VA_ARGS__)
-#define gpiod_warn(desc, fmt, ...)                                            \
-       pr_warn("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
-                 ##__VA_ARGS__)
-#define gpiod_info(desc, fmt, ...)                                            \
-       pr_info("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
-                ##__VA_ARGS__)
-#define gpiod_dbg(desc, fmt, ...)                                             \
-       pr_debug("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\
-                 ##__VA_ARGS__)
-#else
-#define gpiod_emerg(desc, fmt, ...)                                    \
-       pr_emerg("gpio-%d: " fmt, desc_to_gpio(desc), ##__VA_ARGS__)
-#define gpiod_crit(desc, fmt, ...)                                     \
-       pr_crit("gpio-%d: " fmt, desc_to_gpio(desc), ##__VA_ARGS__)
-#define gpiod_err(desc, fmt, ...)                                      \
-       pr_err("gpio-%d: " fmt, desc_to_gpio(desc), ##__VA_ARGS__)
-#define gpiod_warn(desc, fmt, ...)                                     \
-       pr_warn("gpio-%d: " fmt, desc_to_gpio(desc), ##__VA_ARGS__)
-#define gpiod_info(desc, fmt, ...)                                     \
-       pr_info("gpio-%d: " fmt, desc_to_gpio(desc), ##__VA_ARGS__)
-#define gpiod_dbg(desc, fmt, ...)                                      \
-       pr_debug("gpio-%d: " fmt, desc_to_gpio(desc), ##__VA_ARGS__)
-#endif
-
-/* With chip prefix */
-
-#define chip_emerg(chip, fmt, ...)                                     \
-       pr_emerg("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
-#define chip_crit(chip, fmt, ...)                                      \
-       pr_crit("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
-#define chip_err(chip, fmt, ...)                                       \
-       pr_err("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
-#define chip_warn(chip, fmt, ...)                                      \
-       pr_warn("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
-#define chip_info(chip, fmt, ...)                                      \
-       pr_info("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
-#define chip_dbg(chip, fmt, ...)                                       \
-       pr_debug("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
+LIST_HEAD(gpio_chips);
 
 static inline void desc_set_label(struct gpio_desc *d, const char *label)
 {
-#ifdef CONFIG_DEBUG_FS
        d->label = label;
-#endif
-}
-
-/*
- * Return the GPIO number of the passed descriptor relative to its chip
- */
-static int gpio_chip_hwgpio(const struct gpio_desc *desc)
-{
-       return desc - &desc->chip->desc[0];
 }
 
 /**
@@ -291,836 +199,6 @@ int gpiod_get_direction(const struct gpio_desc *desc)
 }
 EXPORT_SYMBOL_GPL(gpiod_get_direction);
 
-#ifdef CONFIG_GPIO_SYSFS
-
-/* lock protects against unexport_gpio() being called while
- * sysfs files are active.
- */
-static DEFINE_MUTEX(sysfs_lock);
-
-/*
- * /sys/class/gpio/gpioN... only for GPIOs that are exported
- *   /direction
- *      * MAY BE OMITTED if kernel won't allow direction changes
- *      * is read/write as "in" or "out"
- *      * may also be written as "high" or "low", initializing
- *        output value as specified ("out" implies "low")
- *   /value
- *      * always readable, subject to hardware behavior
- *      * may be writable, as zero/nonzero
- *   /edge
- *      * configures behavior of poll(2) on /value
- *      * available only if pin can generate IRQs on input
- *      * is read/write as "none", "falling", "rising", or "both"
- *   /active_low
- *      * configures polarity of /value
- *      * is read/write as zero/nonzero
- *      * also affects existing and subsequent "falling" and "rising"
- *        /edge configuration
- */
-
-static ssize_t gpio_direction_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       const struct gpio_desc  *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags)) {
-               status = -EIO;
-       } else {
-               gpiod_get_direction(desc);
-               status = sprintf(buf, "%s\n",
-                       test_bit(FLAG_IS_OUT, &desc->flags)
-                               ? "out" : "in");
-       }
-
-       mutex_unlock(&sysfs_lock);
-       return status;
-}
-
-static ssize_t gpio_direction_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct gpio_desc        *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags))
-               status = -EIO;
-       else if (sysfs_streq(buf, "high"))
-               status = gpiod_direction_output_raw(desc, 1);
-       else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low"))
-               status = gpiod_direction_output_raw(desc, 0);
-       else if (sysfs_streq(buf, "in"))
-               status = gpiod_direction_input(desc);
-       else
-               status = -EINVAL;
-
-       mutex_unlock(&sysfs_lock);
-       return status ? : size;
-}
-
-static /* const */ DEVICE_ATTR(direction, 0644,
-               gpio_direction_show, gpio_direction_store);
-
-static ssize_t gpio_value_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct gpio_desc        *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags))
-               status = -EIO;
-       else
-               status = sprintf(buf, "%d\n", gpiod_get_value_cansleep(desc));
-
-       mutex_unlock(&sysfs_lock);
-       return status;
-}
-
-static ssize_t gpio_value_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct gpio_desc        *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags))
-               status = -EIO;
-       else if (!test_bit(FLAG_IS_OUT, &desc->flags))
-               status = -EPERM;
-       else {
-               long            value;
-
-               status = kstrtol(buf, 0, &value);
-               if (status == 0) {
-                       gpiod_set_value_cansleep(desc, value);
-                       status = size;
-               }
-       }
-
-       mutex_unlock(&sysfs_lock);
-       return status;
-}
-
-static const DEVICE_ATTR(value, 0644,
-               gpio_value_show, gpio_value_store);
-
-static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
-{
-       struct kernfs_node      *value_sd = priv;
-
-       sysfs_notify_dirent(value_sd);
-       return IRQ_HANDLED;
-}
-
-static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
-               unsigned long gpio_flags)
-{
-       struct kernfs_node      *value_sd;
-       unsigned long           irq_flags;
-       int                     ret, irq, id;
-
-       if ((desc->flags & GPIO_TRIGGER_MASK) == gpio_flags)
-               return 0;
-
-       irq = gpiod_to_irq(desc);
-       if (irq < 0)
-               return -EIO;
-
-       id = desc->flags >> ID_SHIFT;
-       value_sd = idr_find(&dirent_idr, id);
-       if (value_sd)
-               free_irq(irq, value_sd);
-
-       desc->flags &= ~GPIO_TRIGGER_MASK;
-
-       if (!gpio_flags) {
-               gpiod_unlock_as_irq(desc);
-               ret = 0;
-               goto free_id;
-       }
-
-       irq_flags = IRQF_SHARED;
-       if (test_bit(FLAG_TRIG_FALL, &gpio_flags))
-               irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
-                       IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
-       if (test_bit(FLAG_TRIG_RISE, &gpio_flags))
-               irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?
-                       IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
-
-       if (!value_sd) {
-               value_sd = sysfs_get_dirent(dev->kobj.sd, "value");
-               if (!value_sd) {
-                       ret = -ENODEV;
-                       goto err_out;
-               }
-
-               ret = idr_alloc(&dirent_idr, value_sd, 1, 0, GFP_KERNEL);
-               if (ret < 0)
-                       goto free_sd;
-               id = ret;
-
-               desc->flags &= GPIO_FLAGS_MASK;
-               desc->flags |= (unsigned long)id << ID_SHIFT;
-
-               if (desc->flags >> ID_SHIFT != id) {
-                       ret = -ERANGE;
-                       goto free_id;
-               }
-       }
-
-       ret = request_any_context_irq(irq, gpio_sysfs_irq, irq_flags,
-                               "gpiolib", value_sd);
-       if (ret < 0)
-               goto free_id;
-
-       ret = gpiod_lock_as_irq(desc);
-       if (ret < 0) {
-               gpiod_warn(desc, "failed to flag the GPIO for IRQ\n");
-               goto free_id;
-       }
-
-       desc->flags |= gpio_flags;
-       return 0;
-
-free_id:
-       idr_remove(&dirent_idr, id);
-       desc->flags &= GPIO_FLAGS_MASK;
-free_sd:
-       if (value_sd)
-               sysfs_put(value_sd);
-err_out:
-       return ret;
-}
-
-static const struct {
-       const char *name;
-       unsigned long flags;
-} trigger_types[] = {
-       { "none",    0 },
-       { "falling", BIT(FLAG_TRIG_FALL) },
-       { "rising",  BIT(FLAG_TRIG_RISE) },
-       { "both",    BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE) },
-};
-
-static ssize_t gpio_edge_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       const struct gpio_desc  *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags))
-               status = -EIO;
-       else {
-               int i;
-
-               status = 0;
-               for (i = 0; i < ARRAY_SIZE(trigger_types); i++)
-                       if ((desc->flags & GPIO_TRIGGER_MASK)
-                                       == trigger_types[i].flags) {
-                               status = sprintf(buf, "%s\n",
-                                                trigger_types[i].name);
-                               break;
-                       }
-       }
-
-       mutex_unlock(&sysfs_lock);
-       return status;
-}
-
-static ssize_t gpio_edge_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct gpio_desc        *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-       int                     i;
-
-       for (i = 0; i < ARRAY_SIZE(trigger_types); i++)
-               if (sysfs_streq(trigger_types[i].name, buf))
-                       goto found;
-       return -EINVAL;
-
-found:
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags))
-               status = -EIO;
-       else {
-               status = gpio_setup_irq(desc, dev, trigger_types[i].flags);
-               if (!status)
-                       status = size;
-       }
-
-       mutex_unlock(&sysfs_lock);
-
-       return status;
-}
-
-static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
-
-static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev,
-                               int value)
-{
-       int                     status = 0;
-
-       if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value)
-               return 0;
-
-       if (value)
-               set_bit(FLAG_ACTIVE_LOW, &desc->flags);
-       else
-               clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
-
-       /* reconfigure poll(2) support if enabled on one edge only */
-       if (dev != NULL && (!!test_bit(FLAG_TRIG_RISE, &desc->flags) ^
-                               !!test_bit(FLAG_TRIG_FALL, &desc->flags))) {
-               unsigned long trigger_flags = desc->flags & GPIO_TRIGGER_MASK;
-
-               gpio_setup_irq(desc, dev, 0);
-               status = gpio_setup_irq(desc, dev, trigger_flags);
-       }
-
-       return status;
-}
-
-static ssize_t gpio_active_low_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       const struct gpio_desc  *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags))
-               status = -EIO;
-       else
-               status = sprintf(buf, "%d\n",
-                               !!test_bit(FLAG_ACTIVE_LOW, &desc->flags));
-
-       mutex_unlock(&sysfs_lock);
-
-       return status;
-}
-
-static ssize_t gpio_active_low_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct gpio_desc        *desc = dev_get_drvdata(dev);
-       ssize_t                 status;
-
-       mutex_lock(&sysfs_lock);
-
-       if (!test_bit(FLAG_EXPORT, &desc->flags)) {
-               status = -EIO;
-       } else {
-               long            value;
-
-               status = kstrtol(buf, 0, &value);
-               if (status == 0)
-                       status = sysfs_set_active_low(desc, dev, value != 0);
-       }
-
-       mutex_unlock(&sysfs_lock);
-
-       return status ? : size;
-}
-
-static const DEVICE_ATTR(active_low, 0644,
-               gpio_active_low_show, gpio_active_low_store);
-
-static const struct attribute *gpio_attrs[] = {
-       &dev_attr_value.attr,
-       &dev_attr_active_low.attr,
-       NULL,
-};
-
-static const struct attribute_group gpio_attr_group = {
-       .attrs = (struct attribute **) gpio_attrs,
-};
-
-/*
- * /sys/class/gpio/gpiochipN/
- *   /base ... matching gpio_chip.base (N)
- *   /label ... matching gpio_chip.label
- *   /ngpio ... matching gpio_chip.ngpio
- */
-
-static ssize_t chip_base_show(struct device *dev,
-                              struct device_attribute *attr, char *buf)
-{
-       const struct gpio_chip  *chip = dev_get_drvdata(dev);
-
-       return sprintf(buf, "%d\n", chip->base);
-}
-static DEVICE_ATTR(base, 0444, chip_base_show, NULL);
-
-static ssize_t chip_label_show(struct device *dev,
-                              struct device_attribute *attr, char *buf)
-{
-       const struct gpio_chip  *chip = dev_get_drvdata(dev);
-
-       return sprintf(buf, "%s\n", chip->label ? : "");
-}
-static DEVICE_ATTR(label, 0444, chip_label_show, NULL);
-
-static ssize_t chip_ngpio_show(struct device *dev,
-                              struct device_attribute *attr, char *buf)
-{
-       const struct gpio_chip  *chip = dev_get_drvdata(dev);
-
-       return sprintf(buf, "%u\n", chip->ngpio);
-}
-static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
-
-static const struct attribute *gpiochip_attrs[] = {
-       &dev_attr_base.attr,
-       &dev_attr_label.attr,
-       &dev_attr_ngpio.attr,
-       NULL,
-};
-
-static const struct attribute_group gpiochip_attr_group = {
-       .attrs = (struct attribute **) gpiochip_attrs,
-};
-
-/*
- * /sys/class/gpio/export ... write-only
- *     integer N ... number of GPIO to export (full access)
- * /sys/class/gpio/unexport ... write-only
- *     integer N ... number of GPIO to unexport
- */
-static ssize_t export_store(struct class *class,
-                               struct class_attribute *attr,
-                               const char *buf, size_t len)
-{
-       long                    gpio;
-       struct gpio_desc        *desc;
-       int                     status;
-
-       status = kstrtol(buf, 0, &gpio);
-       if (status < 0)
-               goto done;
-
-       desc = gpio_to_desc(gpio);
-       /* reject invalid GPIOs */
-       if (!desc) {
-               pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
-               return -EINVAL;
-       }
-
-       /* No extra locking here; FLAG_SYSFS just signifies that the
-        * request and export were done by on behalf of userspace, so
-        * they may be undone on its behalf too.
-        */
-
-       status = gpiod_request(desc, "sysfs");
-       if (status < 0) {
-               if (status == -EPROBE_DEFER)
-                       status = -ENODEV;
-               goto done;
-       }
-       status = gpiod_export(desc, true);
-       if (status < 0)
-               gpiod_free(desc);
-       else
-               set_bit(FLAG_SYSFS, &desc->flags);
-
-done:
-       if (status)
-               pr_debug("%s: status %d\n", __func__, status);
-       return status ? : len;
-}
-
-static ssize_t unexport_store(struct class *class,
-                               struct class_attribute *attr,
-                               const char *buf, size_t len)
-{
-       long                    gpio;
-       struct gpio_desc        *desc;
-       int                     status;
-
-       status = kstrtol(buf, 0, &gpio);
-       if (status < 0)
-               goto done;
-
-       desc = gpio_to_desc(gpio);
-       /* reject bogus commands (gpio_unexport ignores them) */
-       if (!desc) {
-               pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
-               return -EINVAL;
-       }
-
-       status = -EINVAL;
-
-       /* No extra locking here; FLAG_SYSFS just signifies that the
-        * request and export were done by on behalf of userspace, so
-        * they may be undone on its behalf too.
-        */
-       if (test_and_clear_bit(FLAG_SYSFS, &desc->flags)) {
-               status = 0;
-               gpiod_free(desc);
-       }
-done:
-       if (status)
-               pr_debug("%s: status %d\n", __func__, status);
-       return status ? : len;
-}
-
-static struct class_attribute gpio_class_attrs[] = {
-       __ATTR(export, 0200, NULL, export_store),
-       __ATTR(unexport, 0200, NULL, unexport_store),
-       __ATTR_NULL,
-};
-
-static struct class gpio_class = {
-       .name =         "gpio",
-       .owner =        THIS_MODULE,
-
-       .class_attrs =  gpio_class_attrs,
-};
-
-
-/**
- * gpiod_export - export a GPIO through sysfs
- * @gpio: gpio to make available, already requested
- * @direction_may_change: true if userspace may change gpio direction
- * Context: arch_initcall or later
- *
- * When drivers want to make a GPIO accessible to userspace after they
- * have requested it -- perhaps while debugging, or as part of their
- * public interface -- they may use this routine.  If the GPIO can
- * change direction (some can't) and the caller allows it, userspace
- * will see "direction" sysfs attribute which may be used to change
- * the gpio's direction.  A "value" attribute will always be provided.
- *
- * Returns zero on success, else an error.
- */
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
-{
-       unsigned long           flags;
-       int                     status;
-       const char              *ioname = NULL;
-       struct device           *dev;
-       int                     offset;
-
-       /* can't export until sysfs is available ... */
-       if (!gpio_class.p) {
-               pr_debug("%s: called too early!\n", __func__);
-               return -ENOENT;
-       }
-
-       if (!desc) {
-               pr_debug("%s: invalid gpio descriptor\n", __func__);
-               return -EINVAL;
-       }
-
-       mutex_lock(&sysfs_lock);
-
-       spin_lock_irqsave(&gpio_lock, flags);
-       if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
-            test_bit(FLAG_EXPORT, &desc->flags)) {
-               spin_unlock_irqrestore(&gpio_lock, flags);
-               gpiod_dbg(desc, "%s: unavailable (requested=%d, exported=%d)\n",
-                               __func__,
-                               test_bit(FLAG_REQUESTED, &desc->flags),
-                               test_bit(FLAG_EXPORT, &desc->flags));
-               status = -EPERM;
-               goto fail_unlock;
-       }
-
-       if (!desc->chip->direction_input || !desc->chip->direction_output)
-               direction_may_change = false;
-       spin_unlock_irqrestore(&gpio_lock, flags);
-
-       offset = gpio_chip_hwgpio(desc);
-       if (desc->chip->names && desc->chip->names[offset])
-               ioname = desc->chip->names[offset];
-
-       dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
-                           desc, ioname ? ioname : "gpio%u",
-                           desc_to_gpio(desc));
-       if (IS_ERR(dev)) {
-               status = PTR_ERR(dev);
-               goto fail_unlock;
-       }
-
-       status = sysfs_create_group(&dev->kobj, &gpio_attr_group);
-       if (status)
-               goto fail_unregister_device;
-
-       if (direction_may_change) {
-               status = device_create_file(dev, &dev_attr_direction);
-               if (status)
-                       goto fail_unregister_device;
-       }
-
-       if (gpiod_to_irq(desc) >= 0 && (direction_may_change ||
-                                      !test_bit(FLAG_IS_OUT, &desc->flags))) {
-               status = device_create_file(dev, &dev_attr_edge);
-               if (status)
-                       goto fail_unregister_device;
-       }
-
-       set_bit(FLAG_EXPORT, &desc->flags);
-       mutex_unlock(&sysfs_lock);
-       return 0;
-
-fail_unregister_device:
-       device_unregister(dev);
-fail_unlock:
-       mutex_unlock(&sysfs_lock);
-       gpiod_dbg(desc, "%s: status %d\n", __func__, status);
-       return status;
-}
-EXPORT_SYMBOL_GPL(gpiod_export);
-
-static int match_export(struct device *dev, const void *data)
-{
-       return dev_get_drvdata(dev) == data;
-}
-
-/**
- * gpiod_export_link - create a sysfs link to an exported GPIO node
- * @dev: device under which to create symlink
- * @name: name of the symlink
- * @gpio: gpio to create symlink to, already exported
- *
- * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
- * node. Caller is responsible for unlinking.
- *
- * Returns zero on success, else an error.
- */
-int gpiod_export_link(struct device *dev, const char *name,
-                     struct gpio_desc *desc)
-{
-       int                     status = -EINVAL;
-
-       if (!desc) {
-               pr_warn("%s: invalid GPIO\n", __func__);
-               return -EINVAL;
-       }
-
-       mutex_lock(&sysfs_lock);
-
-       if (test_bit(FLAG_EXPORT, &desc->flags)) {
-               struct device *tdev;
-
-               tdev = class_find_device(&gpio_class, NULL, desc, match_export);
-               if (tdev != NULL) {
-                       status = sysfs_create_link(&dev->kobj, &tdev->kobj,
-                                               name);
-               } else {
-                       status = -ENODEV;
-               }
-       }
-
-       mutex_unlock(&sysfs_lock);
-
-       if (status)
-               gpiod_dbg(desc, "%s: status %d\n", __func__, status);
-
-       return status;
-}
-EXPORT_SYMBOL_GPL(gpiod_export_link);
-
-/**
- * gpiod_sysfs_set_active_low - set the polarity of gpio sysfs value
- * @gpio: gpio to change
- * @value: non-zero to use active low, i.e. inverted values
- *
- * Set the polarity of /sys/class/gpio/gpioN/value sysfs attribute.
- * The GPIO does not have to be exported yet.  If poll(2) support has
- * been enabled for either rising or falling edge, it will be
- * reconfigured to follow the new polarity.
- *
- * Returns zero on success, else an error.
- */
-int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
-{
-       struct device           *dev = NULL;
-       int                     status = -EINVAL;
-
-       if (!desc) {
-               pr_warn("%s: invalid GPIO\n", __func__);
-               return -EINVAL;
-       }
-
-       mutex_lock(&sysfs_lock);
-
-       if (test_bit(FLAG_EXPORT, &desc->flags)) {
-               dev = class_find_device(&gpio_class, NULL, desc, match_export);
-               if (dev == NULL) {
-                       status = -ENODEV;
-                       goto unlock;
-               }
-       }
-
-       status = sysfs_set_active_low(desc, dev, value);
-
-unlock:
-       mutex_unlock(&sysfs_lock);
-
-       if (status)
-               gpiod_dbg(desc, "%s: status %d\n", __func__, status);
-
-       return status;
-}
-EXPORT_SYMBOL_GPL(gpiod_sysfs_set_active_low);
-
-/**
- * gpiod_unexport - reverse effect of gpio_export()
- * @gpio: gpio to make unavailable
- *
- * This is implicit on gpio_free().
- */
-void gpiod_unexport(struct gpio_desc *desc)
-{
-       int                     status = 0;
-       struct device           *dev = NULL;
-
-       if (!desc) {
-               pr_warn("%s: invalid GPIO\n", __func__);
-               return;
-       }
-
-       mutex_lock(&sysfs_lock);
-
-       if (test_bit(FLAG_EXPORT, &desc->flags)) {
-
-               dev = class_find_device(&gpio_class, NULL, desc, match_export);
-               if (dev) {
-                       gpio_setup_irq(desc, dev, 0);
-                       clear_bit(FLAG_EXPORT, &desc->flags);
-               } else
-                       status = -ENODEV;
-       }
-
-       mutex_unlock(&sysfs_lock);
-
-       if (dev) {
-               device_unregister(dev);
-               put_device(dev);
-       }
-
-       if (status)
-               gpiod_dbg(desc, "%s: status %d\n", __func__, status);
-}
-EXPORT_SYMBOL_GPL(gpiod_unexport);
-
-static int gpiochip_export(struct gpio_chip *chip)
-{
-       int             status;
-       struct device   *dev;
-
-       /* Many systems register gpio chips for SOC support very early,
-        * before driver model support is available.  In those cases we
-        * export this later, in gpiolib_sysfs_init() ... here we just
-        * verify that _some_ field of gpio_class got initialized.
-        */
-       if (!gpio_class.p)
-               return 0;
-
-       /* use chip->base for the ID; it's already known to be unique */
-       mutex_lock(&sysfs_lock);
-       dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,
-                               "gpiochip%d", chip->base);
-       if (!IS_ERR(dev)) {
-               status = sysfs_create_group(&dev->kobj,
-                               &gpiochip_attr_group);
-       } else
-               status = PTR_ERR(dev);
-       chip->exported = (status == 0);
-       mutex_unlock(&sysfs_lock);
-
-       if (status) {
-               unsigned long   flags;
-               unsigned        gpio;
-
-               spin_lock_irqsave(&gpio_lock, flags);
-               gpio = 0;
-               while (gpio < chip->ngpio)
-                       chip->desc[gpio++].chip = NULL;
-               spin_unlock_irqrestore(&gpio_lock, flags);
-
-               chip_dbg(chip, "%s: status %d\n", __func__, status);
-       }
-
-       return status;
-}
-
-static void gpiochip_unexport(struct gpio_chip *chip)
-{
-       int                     status;
-       struct device           *dev;
-
-       mutex_lock(&sysfs_lock);
-       dev = class_find_device(&gpio_class, NULL, chip, match_export);
-       if (dev) {
-               put_device(dev);
-               device_unregister(dev);
-               chip->exported = false;
-               status = 0;
-       } else
-               status = -ENODEV;
-       mutex_unlock(&sysfs_lock);
-
-       if (status)
-               chip_dbg(chip, "%s: status %d\n", __func__, status);
-}
-
-static int __init gpiolib_sysfs_init(void)
-{
-       int             status;
-       unsigned long   flags;
-       struct gpio_chip *chip;
-
-       status = class_register(&gpio_class);
-       if (status < 0)
-               return status;
-
-       /* Scan and register the gpio_chips which registered very
-        * early (e.g. before the class_register above was called).
-        *
-        * We run before arch_initcall() so chip->dev nodes can have
-        * registered, and so arch_initcall() can always gpio_export().
-        */
-       spin_lock_irqsave(&gpio_lock, flags);
-       list_for_each_entry(chip, &gpio_chips, list) {
-               if (!chip || chip->exported)
-                       continue;
-
-               spin_unlock_irqrestore(&gpio_lock, flags);
-               status = gpiochip_export(chip);
-               spin_lock_irqsave(&gpio_lock, flags);
-       }
-       spin_unlock_irqrestore(&gpio_lock, flags);
-
-
-       return status;
-}
-postcore_initcall(gpiolib_sysfs_init);
-
-#else
-static inline int gpiochip_export(struct gpio_chip *chip)
-{
-       return 0;
-}
-
-static inline void gpiochip_unexport(struct gpio_chip *chip)
-{
-}
-
-#endif /* CONFIG_GPIO_SYSFS */
-
 /*
  * Add a new chip to the global chips list, keeping the list of chips sorted
  * by base order.
@@ -1363,6 +441,11 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
                                  int parent_irq,
                                  irq_flow_handler_t parent_handler)
 {
+       if (gpiochip->can_sleep) {
+               chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n");
+               return;
+       }
+
        irq_set_chained_handler(parent_irq, parent_handler);
        /*
         * The parent irqchip is already using the chip_data for this
@@ -1372,6 +455,12 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
 }
 EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip);
 
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpiochip_irq_lock_class;
+
 /**
  * gpiochip_irq_map() - maps an IRQ into a GPIO irqchip
  * @d: the irqdomain used by this irqchip
@@ -1388,22 +477,35 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
        struct gpio_chip *chip = d->host_data;
 
        irq_set_chip_data(irq, chip);
+       irq_set_lockdep_class(irq, &gpiochip_irq_lock_class);
        irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler);
+       /* Chips that can sleep need nested thread handlers */
+       if (chip->can_sleep)
+               irq_set_nested_thread(irq, 1);
 #ifdef CONFIG_ARM
        set_irq_flags(irq, IRQF_VALID);
 #else
        irq_set_noprobe(irq);
 #endif
-       irq_set_irq_type(irq, chip->irq_default_type);
+       /*
+        * No set-up of the hardware will happen if IRQ_TYPE_NONE
+        * is passed as default type.
+        */
+       if (chip->irq_default_type != IRQ_TYPE_NONE)
+               irq_set_irq_type(irq, chip->irq_default_type);
 
        return 0;
 }
 
 static void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq)
 {
+       struct gpio_chip *chip = d->host_data;
+
 #ifdef CONFIG_ARM
        set_irq_flags(irq, 0);
 #endif
+       if (chip->can_sleep)
+               irq_set_nested_thread(irq, 0);
        irq_set_chip_and_handler(irq, NULL, NULL);
        irq_set_chip_data(irq, NULL);
 }
@@ -1471,7 +573,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *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
+ * @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.
  *
  * This function closely associates a certain irqchip with a certain
  * gpiochip, providing an irq domain to translate the local IRQs to
@@ -1715,7 +818,7 @@ done:
        return status;
 }
 
-static int gpiod_request(struct gpio_desc *desc, const char *label)
+int gpiod_request(struct gpio_desc *desc, const char *label)
 {
        int status = -EPROBE_DEFER;
        struct gpio_chip *chip;
@@ -1780,7 +883,7 @@ static bool __gpiod_free(struct gpio_desc *desc)
        return ret;
 }
 
-static void gpiod_free(struct gpio_desc *desc)
+void gpiod_free(struct gpio_desc *desc)
 {
        if (desc && __gpiod_free(desc))
                module_put(desc->chip->owner);
@@ -1881,8 +984,8 @@ EXPORT_SYMBOL_GPL(gpio_free_array);
  * @offset: of signal within controller's 0..(ngpio - 1) range
  *
  * Returns NULL if the GPIO is not currently requested, else a string.
- * If debugfs support is enabled, the string returned is the label passed
- * to gpio_request(); otherwise it is a meaningless constant.
+ * The string returned is the label passed to gpio_request(); if none has been
+ * passed it is a meaningless, non-NULL constant.
  *
  * This function is for use by GPIO controller drivers.  The label can
  * help with diagnostics, and knowing that the signal is used as a GPIO
@@ -1899,11 +1002,7 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
 
        if (test_bit(FLAG_REQUESTED, &desc->flags) == 0)
                return NULL;
-#ifdef CONFIG_DEBUG_FS
        return desc->label;
-#else
-       return "?";
-#endif
 }
 EXPORT_SYMBOL_GPL(gpiochip_is_requested);
 
@@ -2571,22 +1670,27 @@ void gpiod_add_lookup_table(struct gpiod_lookup_table *table)
        mutex_unlock(&gpio_lookup_lock);
 }
 
-#ifdef CONFIG_OF
 static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
                                      unsigned int idx,
                                      enum gpio_lookup_flags *flags)
 {
+       static const char *suffixes[] = { "gpios", "gpio" };
        char prop_name[32]; /* 32 is max size of property name */
        enum of_gpio_flags of_flags;
        struct gpio_desc *desc;
+       unsigned int i;
 
-       if (con_id)
-               snprintf(prop_name, 32, "%s-gpios", con_id);
-       else
-               snprintf(prop_name, 32, "gpios");
+       for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
+               if (con_id)
+                       snprintf(prop_name, 32, "%s-%s", con_id, suffixes[i]);
+               else
+                       snprintf(prop_name, 32, "%s", suffixes[i]);
 
-       desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
-                                       &of_flags);
+               desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
+                                               &of_flags);
+               if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
+                       break;
+       }
 
        if (IS_ERR(desc))
                return desc;
@@ -2596,14 +1700,6 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
 
        return desc;
 }
-#else
-static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
-                                     unsigned int idx,
-                                     enum gpio_lookup_flags *flags)
-{
-       return ERR_PTR(-ENODEV);
-}
-#endif
 
 static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id,
                                        unsigned int idx,
@@ -2701,7 +1797,7 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
 }
 
 /**
- * gpio_get - obtain a GPIO for a given GPIO function
+ * gpiod_get - obtain a GPIO for a given GPIO function
  * @dev:       GPIO consumer, can be NULL for system-global GPIOs
  * @con_id:    function within the GPIO consumer
  *
@@ -2715,6 +1811,22 @@ struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id)
 }
 EXPORT_SYMBOL_GPL(gpiod_get);
 
+/**
+ * gpiod_get_optional - obtain an optional GPIO for a given GPIO function
+ * @dev: GPIO consumer, can be NULL for system-global GPIOs
+ * @con_id: function within the GPIO consumer
+ *
+ * This is equivalent to gpiod_get(), except that when no GPIO was assigned to
+ * the requested function it will return NULL. This is convenient for drivers
+ * that need to handle optional GPIOs.
+ */
+struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
+                                                 const char *con_id)
+{
+       return gpiod_get_index_optional(dev, con_id, 0);
+}
+EXPORT_SYMBOL_GPL(gpiod_get_optional);
+
 /**
  * gpiod_get_index - obtain a GPIO from a multi-index GPIO function
  * @dev:       GPIO consumer, can be NULL for system-global GPIOs
@@ -2777,6 +1889,33 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(gpiod_get_index);
 
+/**
+ * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
+ *                            function
+ * @dev: GPIO consumer, can be NULL for system-global GPIOs
+ * @con_id: function within the GPIO consumer
+ * @index: index of the GPIO to obtain in the consumer
+ *
+ * This is equivalent to gpiod_get_index(), except that when no GPIO with the
+ * specified index was assigned to the requested function it will return NULL.
+ * This is convenient for drivers that need to handle optional GPIOs.
+ */
+struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
+                                                       const char *con_id,
+                                                       unsigned int index)
+{
+       struct gpio_desc *desc;
+
+       desc = gpiod_get_index(dev, con_id, index);
+       if (IS_ERR(desc)) {
+               if (PTR_ERR(desc) == -ENOENT)
+                       return NULL;
+       }
+
+       return desc;
+}
+EXPORT_SYMBOL_GPL(gpiod_get_index_optional);
+
 /**
  * gpiod_put - dispose of a GPIO descriptor
  * @desc:      GPIO descriptor to dispose of