gpio: simplify adding threaded interrupts
[linux-2.6-block.git] / include / linux / gpio / driver.h
index 24e2cc56beb108bb5364390d5b1f9a148982d295..4b20238e7570e9536bcb469f454fbf43b221c272 100644 (file)
@@ -82,8 +82,6 @@ enum single_ended_mode {
  *     implies that if the chip supports IRQs, these IRQs need to be threaded
  *     as the chip access may sleep when e.g. reading out the IRQ status
  *     registers.
- * @irq_not_threaded: flag must be set if @can_sleep is set but the
- *     IRQs don't need to be threaded
  * @read_reg: reader function for generic GPIO
  * @write_reg: writer function for generic GPIO
  * @pin2mask: some generic GPIO controllers work with the big-endian bits
@@ -109,8 +107,10 @@ enum single_ended_mode {
  *     for GPIO IRQs, provided by GPIO driver
  * @irq_default_type: default IRQ triggering type applied during GPIO driver
  *     initialization, provided by GPIO driver
- * @irq_parent: GPIO IRQ chip parent/bank linux irq number,
- *     provided by GPIO driver
+ * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number,
+ *     provided by GPIO driver for chained interrupt (not for nested
+ *     interrupts).
+ * @irq_nested: True if set the interrupt handling is nested.
  * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all
  *     bits set to one
  * @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to
@@ -166,7 +166,6 @@ struct gpio_chip {
        u16                     ngpio;
        const char              *const *names;
        bool                    can_sleep;
-       bool                    irq_not_threaded;
 
 #if IS_ENABLED(CONFIG_GPIO_GENERIC)
        unsigned long (*read_reg)(void __iomem *reg);
@@ -192,7 +191,8 @@ struct gpio_chip {
        unsigned int            irq_base;
        irq_flow_handler_t      irq_handler;
        unsigned int            irq_default_type;
-       int                     irq_parent;
+       int                     irq_chained_parent;
+       bool                    irq_nested;
        bool                    irq_need_valid_mask;
        unsigned long           *irq_valid_mask;
        struct lock_class_key   *lock_key;
@@ -270,24 +270,40 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
                int parent_irq,
                irq_flow_handler_t parent_handler);
 
+void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip,
+               struct irq_chip *irqchip,
+               int parent_irq);
+
 int _gpiochip_irqchip_add(struct gpio_chip *gpiochip,
                          struct irq_chip *irqchip,
                          unsigned int first_irq,
                          irq_flow_handler_t handler,
                          unsigned int type,
+                         bool nested,
                          struct lock_class_key *lock_key);
 
+/* FIXME: I assume threaded IRQchips do not have the lockdep problem */
+static inline int gpiochip_irqchip_add_nested(struct gpio_chip *gpiochip,
+                         struct irq_chip *irqchip,
+                         unsigned int first_irq,
+                         irq_flow_handler_t handler,
+                         unsigned int type)
+{
+       return _gpiochip_irqchip_add(gpiochip, irqchip, first_irq,
+                                    handler, type, true, NULL);
+}
+
 #ifdef CONFIG_LOCKDEP
 #define gpiochip_irqchip_add(...)                              \
 (                                                              \
        ({                                                      \
                static struct lock_class_key _key;              \
-               _gpiochip_irqchip_add(__VA_ARGS__, &_key);      \
+               _gpiochip_irqchip_add(__VA_ARGS__, false, &_key); \
        })                                                      \
 )
 #else
 #define gpiochip_irqchip_add(...)                              \
-       _gpiochip_irqchip_add(__VA_ARGS__, NULL)
+       _gpiochip_irqchip_add(__VA_ARGS__, false, NULL)
 #endif
 
 #endif /* CONFIG_GPIOLIB_IRQCHIP */