irqchip/sifive-plic: Support irq domain hierarchy
authorYash Shah <yash.shah@sifive.com>
Tue, 10 Dec 2019 11:11:11 +0000 (16:41 +0530)
committerMarc Zyngier <maz@kernel.org>
Mon, 20 Jan 2020 09:24:56 +0000 (09:24 +0000)
Add support for hierarchical irq domains. This is needed as
pre-requisite for gpio-sifive driver.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/1575976274-13487-4-git-send-email-yash.shah@sifive.com
drivers/irqchip/Kconfig
drivers/irqchip/irq-sifive-plic.c

index 697e6a8..bb89dfc 100644 (file)
@@ -490,6 +490,7 @@ config TI_SCI_INTA_IRQCHIP
 config SIFIVE_PLIC
        bool "SiFive Platform-Level Interrupt Controller"
        depends on RISCV
+       select IRQ_DOMAIN_HIERARCHY
        help
           This enables support for the PLIC chip found in SiFive (and
           potentially other) RISC-V systems.  The PLIC controls devices
index 8df547d..0332f60 100644 (file)
@@ -154,15 +154,37 @@ static struct irq_chip plic_chip = {
 static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
                              irq_hw_number_t hwirq)
 {
-       irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq);
-       irq_set_chip_data(irq, NULL);
+       irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
+                           handle_fasteoi_irq, NULL, NULL);
        irq_set_noprobe(irq);
        return 0;
 }
 
+static int plic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+                                unsigned int nr_irqs, void *arg)
+{
+       int i, ret;
+       irq_hw_number_t hwirq;
+       unsigned int type;
+       struct irq_fwspec *fwspec = arg;
+
+       ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < nr_irqs; i++) {
+               ret = plic_irqdomain_map(domain, virq + i, hwirq + i);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static const struct irq_domain_ops plic_irqdomain_ops = {
-       .map            = plic_irqdomain_map,
-       .xlate          = irq_domain_xlate_onecell,
+       .translate      = irq_domain_translate_onecell,
+       .alloc          = plic_irq_domain_alloc,
+       .free           = irq_domain_free_irqs_top,
 };
 
 static struct irq_domain *plic_irqdomain;