Messages in this thread | | | Subject | Re: [PATCH V12 03/10] irqchip: Add LoongArch CPU interrupt controller support | From | Jianmin Lv <> | Date | Mon, 20 Jun 2022 11:06:20 +0800 |
| |
On 2022/6/18 下午6:59, Marc Zyngier wrote: > On Wed, 15 Jun 2022 07:07:23 +0100, > Jianmin Lv <lvjianmin@loongson.cn> wrote: >> >> From: Huacai Chen <chenhuacai@loongson.cn> >> >> 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 <lvjianmin@loongson.cn> >> Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn> >> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> >> --- >> 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 <linux/init.h> >> +#include <linux/kernel.h> >> +#include <linux/interrupt.h> >> +#include <linux/irq.h> >> +#include <linux/irqchip.h> >> +#include <linux/irqdomain.h> >> + >> +#include <asm/loongarch.h> >> +#include <asm/setup.h> >> +#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. >
| |