Merge branch 'kvm-amd-pmu-fixes' into HEAD
[linux-2.6-microblaze.git] / drivers / gpio / gpiolib.c
index 3859911..085348e 100644 (file)
@@ -262,14 +262,14 @@ static int gpiodev_add_to_list(struct gpio_device *gdev)
                return 0;
        }
 
-       next = list_entry(gpio_devices.next, struct gpio_device, list);
+       next = list_first_entry(&gpio_devices, struct gpio_device, list);
        if (gdev->base + gdev->ngpio <= next->base) {
                /* add before first entry */
                list_add(&gdev->list, &gpio_devices);
                return 0;
        }
 
-       prev = list_entry(gpio_devices.prev, struct gpio_device, list);
+       prev = list_last_entry(&gpio_devices, struct gpio_device, list);
        if (prev->base + prev->ngpio <= gdev->base) {
                /* add behind last entry */
                list_add_tail(&gdev->list, &gpio_devices);
@@ -1404,6 +1404,16 @@ static int gpiochip_to_irq(struct gpio_chip *gc, unsigned int offset)
 {
        struct irq_domain *domain = gc->irq.domain;
 
+#ifdef CONFIG_GPIOLIB_IRQCHIP
+       /*
+        * Avoid race condition with other code, which tries to lookup
+        * an IRQ before the irqchip has been properly registered,
+        * i.e. while gpiochip is still being brought up.
+        */
+       if (!gc->irq.initialized)
+               return -EPROBE_DEFER;
+#endif
+
        if (!gpiochip_irqchip_irq_valid(gc, offset))
                return -ENXIO;
 
@@ -1593,6 +1603,15 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,
 
        acpi_gpiochip_request_interrupts(gc);
 
+       /*
+        * Using barrier() here to prevent compiler from reordering
+        * gc->irq.initialized before initialization of above
+        * GPIO chip irq members.
+        */
+       barrier();
+
+       gc->irq.initialized = true;
+
        return 0;
 }
 
@@ -2227,6 +2246,16 @@ static int gpio_set_bias(struct gpio_desc *desc)
        return gpio_set_config_with_argument_optional(desc, bias, arg);
 }
 
+/**
+ * gpio_set_debounce_timeout() - Set debounce timeout
+ * @desc:      GPIO descriptor to set the debounce timeout
+ * @debounce:  Debounce timeout in microseconds
+ *
+ * The function calls the certain GPIO driver to set debounce timeout
+ * in the hardware.
+ *
+ * Returns 0 on success, or negative error code otherwise.
+ */
 int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce)
 {
        return gpio_set_config_with_argument_optional(desc,
@@ -3147,6 +3176,16 @@ int gpiod_to_irq(const struct gpio_desc *desc)
 
                return retirq;
        }
+#ifdef CONFIG_GPIOLIB_IRQCHIP
+       if (gc->irq.chip) {
+               /*
+                * Avoid race condition with other code, which tries to lookup
+                * an IRQ before the irqchip has been properly registered,
+                * i.e. while gpiochip is still being brought up.
+                */
+               return -EPROBE_DEFER;
+       }
+#endif
        return -ENXIO;
 }
 EXPORT_SYMBOL_GPL(gpiod_to_irq);
@@ -3931,23 +3970,21 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
         * If a connection label was passed use that, else attempt to use
         * the device name as label
         */
-       ret = gpiod_request(desc, con_id ? con_id : devname);
+       ret = gpiod_request(desc, con_id ?: devname);
        if (ret) {
-               if (ret == -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 {
+               if (!(ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
                        return ERR_PTR(ret);
-               }
+
+               /*
+                * This happens when there are several consumers for
+                * the same GPIO line: we just return here without
+                * further initialization. It is a bit of 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 ?: devname);
+               return desc;
        }
 
        ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
@@ -4102,12 +4139,11 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
  */
 static void gpiochip_free_hogs(struct gpio_chip *gc)
 {
+       struct gpio_desc *desc;
        int id;
 
-       for (id = 0; id < gc->ngpio; id++) {
-               if (test_bit(FLAG_IS_HOGGED, &gc->gpiodev->descs[id].flags))
-                       gpiochip_free_own_desc(&gc->gpiodev->descs[id]);
-       }
+       for_each_gpio_desc_with_flag(id, gc, desc, FLAG_IS_HOGGED)
+               gpiochip_free_own_desc(desc);
 }
 
 /**
@@ -4426,7 +4462,7 @@ static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)
        if (list_is_last(&gdev->list, &gpio_devices))
                ret = NULL;
        else
-               ret = list_entry(gdev->list.next, struct gpio_device, list);
+               ret = list_first_entry(&gdev->list, struct gpio_device, list);
        spin_unlock_irqrestore(&gpio_lock, flags);
 
        s->private = "\n";