Message ID | 20230303133647.845095-15-sunilvl@ventanamicro.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add basic ACPI support for RISC-V | expand |
Context | Check | Description |
---|---|---|
conchuod/tree_selection | fail | Failed to apply to next/pending-fixes or riscv/for-next |
On Fri, Mar 03, 2023 at 07:06:41PM +0530, Sunil V L wrote: > Add support for initializing the RISC-V INTC driver on ACPI > platforms. > > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > Reviewed-by: Andrew Jones <ajones@ventanamicro.com> > --- > drivers/irqchip/irq-riscv-intc.c | 77 +++++++++++++++++++++++++++----- > 1 file changed, 65 insertions(+), 12 deletions(-) > > diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c > index f229e3e66387..f522510dc1f3 100644 > --- a/drivers/irqchip/irq-riscv-intc.c > +++ b/drivers/irqchip/irq-riscv-intc.c > @@ -6,6 +6,7 @@ > */ > > #define pr_fmt(fmt) "riscv-intc: " fmt > +#include <linux/acpi.h> > #include <linux/atomic.h> > #include <linux/bits.h> > #include <linux/cpu.h> > @@ -112,6 +113,30 @@ static struct fwnode_handle *riscv_intc_hwnode(void) > return intc_domain->fwnode; > } > > +static int __init riscv_intc_init_common(struct fwnode_handle *fn) > +{ > + int rc; > + > + intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG, > + &riscv_intc_domain_ops, NULL); > + if (!intc_domain) { > + pr_err("unable to add IRQ domain\n"); > + return -ENXIO; > + } > + > + rc = set_handle_irq(&riscv_intc_irq); > + if (rc) { > + pr_err("failed to set irq handler\n"); > + return rc; > + } > + > + riscv_set_intc_hwnode_fn(riscv_intc_hwnode); > + > + pr_info("%d local interrupts mapped\n", BITS_PER_LONG); > + > + return 0; > +} > + > static int __init riscv_intc_init(struct device_node *node, > struct device_node *parent) > { > @@ -133,24 +158,52 @@ static int __init riscv_intc_init(struct device_node *node, > if (riscv_hartid_to_cpuid(hartid) != smp_processor_id()) > return 0; > > - intc_domain = irq_domain_add_linear(node, BITS_PER_LONG, > - &riscv_intc_domain_ops, NULL); > - if (!intc_domain) { > - pr_err("unable to add IRQ domain\n"); > - return -ENXIO; > - } > - > - rc = set_handle_irq(&riscv_intc_irq); > + rc = riscv_intc_init_common(of_node_to_fwnode(node)); > if (rc) { > - pr_err("failed to set irq handler\n"); > + pr_err("failed to initialize INTC\n"); The early return paths from riscv_intc_init_common() all print something, is also printing here redundant? This seems fine to me otherwise though, Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Thanks, Conor. > return rc; > } > > - riscv_set_intc_hwnode_fn(riscv_intc_hwnode); > + return 0; > +} > > - pr_info("%d local interrupts mapped\n", BITS_PER_LONG); > +IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init); > + > +#ifdef CONFIG_ACPI > + > +static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, > + const unsigned long end) > +{ > + int rc; > + struct fwnode_handle *fn; > + struct acpi_madt_rintc *rintc; > + > + rintc = (struct acpi_madt_rintc *)header; > + > + /* > + * The ACPI MADT will have one INTC for each CPU (or HART) > + * so riscv_intc_acpi_init() function will be called once > + * for each INTC. We only do INTC initialization > + * for the INTC belonging to the boot CPU (or boot HART). > + */ > + if (riscv_hartid_to_cpuid(rintc->hart_id) != smp_processor_id()) > + return 0; > + > + fn = irq_domain_alloc_named_fwnode("RISCV-INTC"); > + if (!fn) { > + pr_err("unable to allocate INTC FW node\n"); > + return -ENOMEM; > + } > + > + rc = riscv_intc_init_common(fn); > + if (rc) { > + pr_err("failed to initialize INTC\n"); > + return rc; > + } > > return 0; > } > > -IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init); > +IRQCHIP_ACPI_DECLARE(riscv_intc, ACPI_MADT_TYPE_RINTC, NULL, > + ACPI_MADT_RINTC_VERSION_V1, riscv_intc_acpi_init); > +#endif > -- > 2.34.1 >
diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c index f229e3e66387..f522510dc1f3 100644 --- a/drivers/irqchip/irq-riscv-intc.c +++ b/drivers/irqchip/irq-riscv-intc.c @@ -6,6 +6,7 @@ */ #define pr_fmt(fmt) "riscv-intc: " fmt +#include <linux/acpi.h> #include <linux/atomic.h> #include <linux/bits.h> #include <linux/cpu.h> @@ -112,6 +113,30 @@ static struct fwnode_handle *riscv_intc_hwnode(void) return intc_domain->fwnode; } +static int __init riscv_intc_init_common(struct fwnode_handle *fn) +{ + int rc; + + intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG, + &riscv_intc_domain_ops, NULL); + if (!intc_domain) { + pr_err("unable to add IRQ domain\n"); + return -ENXIO; + } + + rc = set_handle_irq(&riscv_intc_irq); + if (rc) { + pr_err("failed to set irq handler\n"); + return rc; + } + + riscv_set_intc_hwnode_fn(riscv_intc_hwnode); + + pr_info("%d local interrupts mapped\n", BITS_PER_LONG); + + return 0; +} + static int __init riscv_intc_init(struct device_node *node, struct device_node *parent) { @@ -133,24 +158,52 @@ static int __init riscv_intc_init(struct device_node *node, if (riscv_hartid_to_cpuid(hartid) != smp_processor_id()) return 0; - intc_domain = irq_domain_add_linear(node, BITS_PER_LONG, - &riscv_intc_domain_ops, NULL); - if (!intc_domain) { - pr_err("unable to add IRQ domain\n"); - return -ENXIO; - } - - rc = set_handle_irq(&riscv_intc_irq); + rc = riscv_intc_init_common(of_node_to_fwnode(node)); if (rc) { - pr_err("failed to set irq handler\n"); + pr_err("failed to initialize INTC\n"); return rc; } - riscv_set_intc_hwnode_fn(riscv_intc_hwnode); + return 0; +} - pr_info("%d local interrupts mapped\n", BITS_PER_LONG); +IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init); + +#ifdef CONFIG_ACPI + +static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, + const unsigned long end) +{ + int rc; + struct fwnode_handle *fn; + struct acpi_madt_rintc *rintc; + + rintc = (struct acpi_madt_rintc *)header; + + /* + * The ACPI MADT will have one INTC for each CPU (or HART) + * so riscv_intc_acpi_init() function will be called once + * for each INTC. We only do INTC initialization + * for the INTC belonging to the boot CPU (or boot HART). + */ + if (riscv_hartid_to_cpuid(rintc->hart_id) != smp_processor_id()) + return 0; + + fn = irq_domain_alloc_named_fwnode("RISCV-INTC"); + if (!fn) { + pr_err("unable to allocate INTC FW node\n"); + return -ENOMEM; + } + + rc = riscv_intc_init_common(fn); + if (rc) { + pr_err("failed to initialize INTC\n"); + return rc; + } return 0; } -IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init); +IRQCHIP_ACPI_DECLARE(riscv_intc, ACPI_MADT_TYPE_RINTC, NULL, + ACPI_MADT_RINTC_VERSION_V1, riscv_intc_acpi_init); +#endif