From: Thierry Reding <tred...@nvidia.com>

Hierarchical IRQ domains can be used to stack different IRQ controllers
on top of each other. One specific use-case where this can be useful is
if a power management controller has top-level controls for wakeup
interrupts. In such cases, the power management controller can be a
parent to other interrupt controllers and program additional registers
when an IRQ has its wake capability enabled or disabled.

Signed-off-by: Thierry Reding <tred...@nvidia.com>
Signed-off-by: Lina Iyer <il...@codeaurora.org>
---
 drivers/gpio/gpiolib.c      | 15 +++++++++++----
 include/linux/gpio/driver.h |  6 ++++++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d1adfdf50fb3..46ccb9b174b9 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1895,7 +1895,9 @@ static int gpiochip_add_irqchip(struct gpio_chip 
*gpiochip,
                type = IRQ_TYPE_NONE;
        }
 
-       gpiochip->to_irq = gpiochip_to_irq;
+       if (!gpiochip->to_irq)
+               gpiochip->to_irq = gpiochip_to_irq;
+
        gpiochip->irq.default_type = type;
        gpiochip->irq.lock_key = lock_key;
        gpiochip->irq.request_key = request_key;
@@ -1905,9 +1907,14 @@ static int gpiochip_add_irqchip(struct gpio_chip 
*gpiochip,
        else
                ops = &gpiochip_domain_ops;
 
-       gpiochip->irq.domain = irq_domain_add_simple(np, gpiochip->ngpio,
-                                                    gpiochip->irq.first,
-                                                    ops, gpiochip);
+       if (gpiochip->irq.parent_domain)
+               gpiochip->irq.domain = 
irq_domain_add_hierarchy(gpiochip->irq.parent_domain,
+                                                               0, 
gpiochip->ngpio,
+                                                               np, ops, 
gpiochip);
+       else
+               gpiochip->irq.domain = irq_domain_add_simple(np, 
gpiochip->ngpio,
+                                                            
gpiochip->irq.first,
+                                                            ops, gpiochip);
        if (!gpiochip->irq.domain)
                return -EINVAL;
 
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 07cddbf45186..88ef196f96ec 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -48,6 +48,12 @@ struct gpio_irq_chip {
         */
        const struct irq_domain_ops *domain_ops;
 
+       /**
+        * @parent_domain:
+        *
+        */
+       struct irq_domain *parent_domain;
+
        /**
         * @handler:
         *
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

Reply via email to