Messages in this thread Patch in this message |  | | From | Jianmin Lv <> | Subject | [PATCH V14 14/15] irqchip / ACPI: Introduce ACPI_IRQ_MODEL_LPIC for LoongArch | Date | Sun, 3 Jul 2022 16:45:31 +0800 |
| |
For LoongArch, ACPI_IRQ_MODEL_LPIC is introduced, and then the callback acpi_get_gsi_domain_id and acpi_gsi_to_irq_fallback are implemented.
The acpi_get_gsi_domain_id callback returns related fwnode handle of irqdomain for different GSI range.
The acpi_gsi_to_irq_fallback will create new mapping for gsi when the mapping of it is not found.
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn> --- drivers/acpi/bus.c | 3 +++ drivers/irqchip/irq-loongarch-cpu.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 1 + 3 files changed, 41 insertions(+)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 86fa61a..63fbf00 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1145,6 +1145,9 @@ static int __init acpi_bus_init_irq(void) case ACPI_IRQ_MODEL_PLATFORM: message = "platform specific model"; break; + case ACPI_IRQ_MODEL_LPIC: + message = "LPIC"; + break; default: pr_info("Unknown interrupt routing model\n"); return -ENODEV; diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c index c2f7411..1b241d7 100644 --- a/drivers/irqchip/irq-loongarch-cpu.c +++ b/drivers/irqchip/irq-loongarch-cpu.c @@ -15,6 +15,41 @@ static struct irq_domain *irq_domain; +static int lpic_gsi_to_irq(u32 gsi) +{ + /* Only pch irqdomain transferring is required for LoongArch. */ + if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ) + return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); + return -1; +} + +static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi) +{ + int id; + struct fwnode_handle *domain_handle = NULL; + + switch (gsi) { + case GSI_MIN_CPU_IRQ ... GSI_MAX_CPU_IRQ: + if (liointc_handle) + domain_handle = liointc_handle; + break; + + case GSI_MIN_LPC_IRQ ... GSI_MAX_LPC_IRQ: + if (pch_lpc_handle) + domain_handle = pch_lpc_handle; + break; + + case GSI_MIN_PCH_IRQ ... GSI_MAX_PCH_IRQ: + id = find_pch_pic(gsi); + if (id >= 0 && pch_pic_handle[id]) + domain_handle = pch_pic_handle[id]; + + break; + } + + return domain_handle; +} + static void mask_loongarch_irq(struct irq_data *d) { clear_csr_ecfg(ECFGF(d->hwirq)); @@ -87,6 +122,8 @@ static int __init loongarch_cpu_irq_init(void) panic("Failed to add irqdomain for LoongArch CPU"); set_handle_irq(&handle_cpu_irq); + acpi_set_irq_model(ACPI_IRQ_MODEL_LPIC, lpic_get_gsi_domain_id); + acpi_set_gsi_to_irq_fallback(lpic_gsi_to_irq); return 0; } diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 71d3719..1bec0a3 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -105,6 +105,7 @@ enum acpi_irq_model_id { ACPI_IRQ_MODEL_IOSAPIC, ACPI_IRQ_MODEL_PLATFORM, ACPI_IRQ_MODEL_GIC, + ACPI_IRQ_MODEL_LPIC, ACPI_IRQ_MODEL_COUNT }; -- 1.8.3.1
|  |