soc/tegra: pmc: Add support for simple wake events
authorThierry Reding <treding@nvidia.com>
Mon, 11 Jul 2022 15:40:30 +0000 (17:40 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 15 Sep 2022 10:39:34 +0000 (12:39 +0200)
Simple wake events are neither mapped to GIC interrupts nor have an
associated GPIO line. They are close to GPIO-backed wake events in that
the IRQ hierarchy processing needs to stop at the PMC level, but since
there is no dedicated GPIO line for them, let's turn them into a
separate type.

Signed-off-by: Thierry Reding <treding@nvidia.com>
drivers/soc/tegra/pmc.c

index 0e87fdb..48286bc 100644 (file)
@@ -296,6 +296,17 @@ struct tegra_wake_event {
        } gpio;
 };
 
+#define TEGRA_WAKE_SIMPLE(_name, _id)                  \
+       {                                               \
+               .name = _name,                          \
+               .id = _id,                              \
+               .irq = 0,                               \
+               .gpio = {                               \
+                       .instance = UINT_MAX,           \
+                       .pin = UINT_MAX,                \
+               },                                      \
+       }
+
 #define TEGRA_WAKE_IRQ(_name, _id, _irq)               \
        {                                               \
                .name = _name,                          \
@@ -2239,6 +2250,7 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
        for (i = 0; i < soc->num_wake_events; i++) {
                const struct tegra_wake_event *event = &soc->wake_events[i];
 
+               /* IRQ and simple wake events */
                if (fwspec->param_count == 2) {
                        struct irq_fwspec spec;
 
@@ -2251,6 +2263,12 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
                        if (err < 0)
                                break;
 
+                       /* simple hierarchies stop at the PMC level */
+                       if (event->irq == 0) {
+                               err = irq_domain_disconnect_hierarchy(domain->parent, virq);
+                               break;
+                       }
+
                        spec.fwnode = &pmc->dev->of_node->fwnode;
                        spec.param_count = 3;
                        spec.param[0] = GIC_SPI;
@@ -2263,6 +2281,7 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq,
                        break;
                }
 
+               /* GPIO wake events */
                if (fwspec->param_count == 3) {
                        if (event->gpio.instance != fwspec->param[0] ||
                            event->gpio.pin != fwspec->param[1])