Linux-Kernel Archive: Re: [PATCH V12 03/10] irqchip: Add LoongArch CPU interrupt controller support Re: [PATCH V12 03/10] irqchip: Add LoongArch CPU interrupt controller support From: Jianmin Lv Date: Sun Jun 19 2022 - 23:06:50 EST Next message: huangguangbin (A): "Re: [RESEND PATCH V7 0/2] drivers/perf: hisi: Add driver for HNS3 PMU" Previous message: Liu Ying: "Re: [PATCH 1/2] dt-bindings: phy: Add Freescale i.MX8qm Mixel LVDS PHY binding" In reply to: Marc Zyngier: "Re: [PATCH V12 03/10] irqchip: Add LoongArch CPU interrupt controller support" Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] On 2022/6/18 下午6:59, Marc Zyngier wrote: On Wed, 15 Jun 2022 07:07:23 +0100, Jianmin Lv
wrote: From: Huacai Chen LoongArch CPUINTC stands for CSR.ECFG/CSR.ESTAT and related interrupt controller that described in Section 7.4 of "LoongArch Reference Manual, Vol 1". For more information please refer Documentation/loongarch/irq- chip-model.rst. LoongArch CPUINTC has 13 interrupt sources: SWI0~1, HWI0~7, IPI, TI (Timer) and PCOV (PMC). IRQ mappings of HWI0~7 are configurable (can be created from DT/ACPI), but IPI, TI (Timer) and PCOV (PMC) are hardcoded bits, so we define get_xxx_irq() for them. Change-Id: I53fb0be768daeeecc90d0ccc0bb0becd3d4e6984 Please drop this Change-Id. The upstream kernel doesn't use Gerrit. Ok, I'll check it before submitting patch series to avoid this. Co-developed-by: Jianmin Lv Signed-off-by: Jianmin Lv Signed-off-by: Huacai Chen --- drivers/acpi/bus.c | 3 + drivers/irqchip/Kconfig | 10 +++ drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-loongarch-cpu.c | 134 ++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 1 + 5 files changed, 149 insertions(+) create mode 100644 drivers/irqchip/irq-loongarch-cpu.c 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; This should be part of the patch that deals with the ACPI-specific part of the architecture, which is the following patch. Ok, I'll put the change in the following another patch. default: pr_info("Unknown interrupt routing model\n"); return -ENODEV; diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 4ab1038..4126b1c 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -546,6 +546,16 @@ config EXYNOS_IRQ_COMBINER Say yes here to add support for the IRQ combiner devices embedded in Samsung Exynos chips. +config IRQ_LOONGARCH_CPU + bool + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN + select GENERIC_IRQ_EFFECTIVE_AFF_MASK + help + Support for the LoongArch CPU Interrupt Controller. For details of + irq chip hierarchy on LoongArch platforms please read the document + Documentation/loongarch/irq-chip-model.rst. + config LOONGSON_LIOINTC bool "Loongson Local I/O Interrupt Controller" depends on MACH_LOONGSON64 diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 5b67450..6894a13 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -103,6 +103,7 @@ obj-$(CONFIG_LS1X_IRQ) += irq-ls1x.o obj-$(CONFIG_TI_SCI_INTR_IRQCHIP) += irq-ti-sci-intr.o obj-$(CONFIG_TI_SCI_INTA_IRQCHIP) += irq-ti-sci-inta.o obj-$(CONFIG_TI_PRUSS_INTC) += irq-pruss-intc.o +obj-$(CONFIG_IRQ_LOONGARCH_CPU) += irq-loongarch-cpu.o obj-$(CONFIG_LOONGSON_LIOINTC) += irq-loongson-liointc.o obj-$(CONFIG_LOONGSON_HTPIC) += irq-loongson-htpic.o obj-$(CONFIG_LOONGSON_HTVEC) += irq-loongson-htvec.o diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c new file mode 100644 index 0000000..c382bd9 --- /dev/null +++ b/drivers/irqchip/irq-loongarch-cpu.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020-2022 Loongson Technology Corporation Limited + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include "irq-loongarch-pic-common.h" + +static struct irq_domain *irq_domain; + +static void mask_loongarch_irq(struct irq_data *d) +{ + clear_csr_ecfg(ECFGF(d->hwirq)); +} + +static void unmask_loongarch_irq(struct irq_data *d) +{ + set_csr_ecfg(ECFGF(d->hwirq)); +} + +static struct irq_chip cpu_irq_controller = { + .name = "LoongArch", Why is it "LoongArch" and not "CPUINTC", which would make a lot more sense? I think "CPUINTC" should make more sense, maybe Huacai think "LoongArch" is better, like "MIPS" in mips cpu irqchip driver, but I prefer "CPUINTC", like "LAPIC" of x86 and "GIC" of arm, a name of irqchip instead of a name of an architecture. Huacai, what do you think? + .irq_mask = mask_loongarch_irq, + .irq_unmask = unmask_loongarch_irq, +}; + +static void handle_cpu_irq(struct pt_regs *regs) +{ + int hwirq; + unsigned int estat = read_csr_estat() & CSR_ESTAT_IS; + + while ((hwirq = ffs(estat))) { + estat &= ~BIT(hwirq - 1); + generic_handle_domain_irq(irq_domain, hwirq - 1); + } +} + +int get_ipi_irq(void) +{ + return irq_create_mapping(irq_domain, EXCCODE_IPI - EXCCODE_INT_START); +} + +int get_pmc_irq(void) +{ + return irq_create_mapping(irq_domain, EXCCODE_PMC - EXCCODE_INT_START); +} + +int get_timer_irq(void) +{ + return irq_create_mapping(irq_domain, EXCCODE_TIMER - EXCCODE_INT_START); +} + +static int loongarch_cpu_intc_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) +{ + irq_set_noprobe(irq); + irq_set_chip_and_handler(irq, &cpu_irq_controller, handle_percpu_irq); + + return 0; +} + +static const struct irq_domain_ops loongarch_cpu_intc_irq_domain_ops = { + .map = loongarch_cpu_intc_map, + .xlate = irq_domain_xlate_onecell, +}; + +struct irq_domain * __init loongarch_cpu_irq_init(void) +{ + struct fwnode_handle *domain_handle; + + /* Mask interrupts. */ + clear_csr_ecfg(ECFG0_IM); + clear_csr_estat(ESTATF_IP); + + domain_handle = irq_domain_alloc_fwnode(NULL); Please don't use NULL here, as this is supposed to be a physical address. If you don't have any physical address at hand (because this driver isn't using MMIO), use irq_domain_alloc_named_fwnode() instead. Ok, I'll fix it in next version. + irq_domain = irq_domain_create_linear(domain_handle, EXCCODE_INT_NUM, + &loongarch_cpu_intc_irq_domain_ops, NULL); + + if (!irq_domain) + 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); lpic_get_gsi_domain_id only gets defined in the following patch, so the series cannot be bisected. Please fix this (the series should compile every step of the way). Ok, I'll fix it in next version. + + return irq_domain; +} + +static int __init +liointc_parse_madt(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_madt_lio_pic *liointc_entry = (struct acpi_madt_lio_pic *)header; + + return liointc_acpi_init(irq_domain, liointc_entry); +} + +static int __init +eiointc_parse_madt(union acpi_subtable_headers *header, + const unsigned long end) +{ + struct acpi_madt_eio_pic *eiointc_entry = (struct acpi_madt_eio_pic *)header; + + return eiointc_acpi_init(irq_domain, eiointc_entry); +} +static int __init acpi_cascade_irqdomain_init(void) +{ + acpi_table_parse_madt(ACPI_MADT_TYPE_LIO_PIC, + liointc_parse_madt, 0); + acpi_table_parse_madt(ACPI_MADT_TYPE_EIO_PIC, + eiointc_parse_madt, 0); + return 0; +} +static int __init coreintc_acpi_init_v1(union acpi_subtable_headers *header, + const unsigned long end) +{ + if (irq_domain) + return 0; + + init_vector_parent_group(); + loongarch_cpu_irq_init(); + acpi_cascade_irqdomain_init(); + return 0; +} +IRQCHIP_ACPI_DECLARE(coreintc_v1, ACPI_MADT_TYPE_CORE_PIC, + NULL, ACPI_MADT_CORE_PIC_VERSION_V1, + coreintc_acpi_init_v1); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 957e23f..d2f5108 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, This hunk should be moved to the patch that introduces lpic_get_gsi_domain_id. Ok, I'll move it to the patch that introduces lpic_get_gsi_domain_id in next version. Thanks, M. Next message: huangguangbin (A): "Re: [RESEND PATCH V7 0/2] drivers/perf: hisi: Add driver for HNS3 PMU" Previous message: Liu Ying: "Re: [PATCH 1/2] dt-bindings: phy: Add Freescale i.MX8qm Mixel LVDS PHY binding" In reply to: Marc Zyngier: "Re: [PATCH V12 03/10] irqchip: Add LoongArch CPU interrupt controller support" Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]