Merge tag 'hte/for-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra...
[linux-block.git] / include / linux / gpio / driver.h
index 0ce96ebdaa36905b33fe007d8b0e485fc8d8f2ba..b1e0f1f8ee2e70d327aa50a6da9e196457aa502f 100644 (file)
@@ -3,13 +3,14 @@
 #define __LINUX_GPIO_DRIVER_H
 
 #include <linux/device.h>
-#include <linux/types.h>
 #include <linux/irq.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/lockdep.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinconf-generic.h>
+#include <linux/property.h>
+#include <linux/types.h>
 
 struct gpio_desc;
 struct of_phandle_args;
@@ -221,6 +222,15 @@ struct gpio_irq_chip {
         */
        bool per_parent_data;
 
+       /**
+        * @initialized:
+        *
+        * Flag to track GPIO chip irq member's initialization.
+        * This flag will make sure GPIO chip irq members are not used
+        * before they are initialized.
+        */
+       bool initialized;
+
        /**
         * @init_hw: optional routine to initialize hardware before
         * an IRQ chip will be added. This is quite useful when
@@ -446,7 +456,7 @@ struct gpio_chip {
        void __iomem *reg_dir_in;
        bool bgpio_dir_unreadable;
        int bgpio_bits;
-       spinlock_t bgpio_lock;
+       raw_spinlock_t bgpio_lock;
        unsigned long bgpio_data;
        unsigned long bgpio_dir;
 #endif /* CONFIG_GPIO_GENERIC */
@@ -502,6 +512,18 @@ struct gpio_chip {
         */
        int (*of_xlate)(struct gpio_chip *gc,
                        const struct of_phandle_args *gpiospec, u32 *flags);
+
+       /**
+        * @of_gpio_ranges_fallback:
+        *
+        * Optional hook for the case that no gpio-ranges property is defined
+        * within the device tree node "np" (usually DT before introduction
+        * of gpio-ranges). So this callback is helpful to provide the
+        * necessary backward compatibility for the pin ranges.
+        */
+       int (*of_gpio_ranges_fallback)(struct gpio_chip *gc,
+                                      struct device_node *np);
+
 #endif /* CONFIG_OF_GPIO */
 };
 
@@ -589,6 +611,22 @@ void gpiochip_relres_irq(struct gpio_chip *gc, unsigned int offset);
 void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset);
 void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset);
 
+/* irq_data versions of the above */
+int gpiochip_irq_reqres(struct irq_data *data);
+void gpiochip_irq_relres(struct irq_data *data);
+
+/* Paste this in your irq_chip structure  */
+#define        GPIOCHIP_IRQ_RESOURCE_HELPERS                                   \
+               .irq_request_resources  = gpiochip_irq_reqres,          \
+               .irq_release_resources  = gpiochip_irq_relres
+
+static inline void gpio_irq_chip_set_chip(struct gpio_irq_chip *girq,
+                                         const struct irq_chip *chip)
+{
+       /* Yes, dropping const is ugly, but it isn't like we have a choice */
+       girq->chip = (struct irq_chip *)chip;
+}
+
 /* Line status inquiry for drivers */
 bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset);
 bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset);
@@ -760,4 +798,29 @@ static inline void gpiochip_unlock_as_irq(struct gpio_chip *gc,
 }
 #endif /* CONFIG_GPIOLIB */
 
+#define for_each_gpiochip_node(dev, child)                                     \
+       device_for_each_child_node(dev, child)                                  \
+               if (!fwnode_property_present(child, "gpio-controller")) {} else
+
+static inline unsigned int gpiochip_node_count(struct device *dev)
+{
+       struct fwnode_handle *child;
+       unsigned int count = 0;
+
+       for_each_gpiochip_node(dev, child)
+               count++;
+
+       return count;
+}
+
+static inline struct fwnode_handle *gpiochip_node_get_first(struct device *dev)
+{
+       struct fwnode_handle *fwnode;
+
+       for_each_gpiochip_node(dev, fwnode)
+               return fwnode;
+
+       return NULL;
+}
+
 #endif /* __LINUX_GPIO_DRIVER_H */