All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers
@ 2022-05-15  3:37 Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 01/10] irqchip: Adjust Kconfig for Loongson Jianmin Lv
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-15  3:37 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen,
	Jianmin Lv

LoongArch is a new RISC ISA, which is a bit like MIPS or RISC-V.
LoongArch includes a reduced 32-bit version (LA32R), a standard 32-bit
version (LA32S) and a 64-bit version (LA64). LoongArch use ACPI as its
boot protocol LoongArch-specific interrupt controllers (similar to APIC)
are already added in the ACPI Specification 6.5(which may be published in
early June this year and the board is reviewing the draft).

Currently, LoongArch based processors (e.g. Loongson-3A5000) can only
work together with LS7A chipsets. The irq chips in LoongArch computers
include CPUINTC (CPU Core Interrupt Controller), LIOINTC (Legacy I/O
Interrupt Controller), EIOINTC (Extended I/O Interrupt Controller),
HTVECINTC (Hyper-Transport Vector Interrupt Controller), PCH-PIC (Main
Interrupt Controller in LS7A chipset), PCH-LPC (LPC Interrupt Controller
in LS7A chipset) and PCH-MSI (MSI Interrupt Controller).

CPUINTC is a per-core controller (in CPU), LIOINTC/EIOINTC/HTVECINTC are
per-package controllers (in CPU), while PCH-PIC/PCH-LPC/PCH-MSI are all
controllers out of CPU (i.e., in chipsets). These controllers (in other
words, irqchips) are linked in a hierarchy, and there are two models of
hierarchy (legacy model and extended model). 

Legacy IRQ model:

In this model, the IPI (Inter-Processor Interrupt) and CPU Local Timer
interrupt go to CPUINTC directly, CPU UARTS interrupts go to LIOINTC,
while all other devices interrupts go to PCH-PIC/PCH-LPC/PCH-MSI and
gathered by HTVECINTC, and then go to LIOINTC, and then CPUINTC.

 +---------------------------------------------+
 |                                             |
 |    +-----+     +---------+     +-------+    |
 |    | IPI | --> | CPUINTC | <-- | Timer |    |
 |    +-----+     +---------+     +-------+    |
 |                     ^                       |
 |                     |                       |
 |                +---------+     +-------+    |
 |                | LIOINTC | <-- | UARTs |    |
 |                +---------+     +-------+    |
 |                     ^                       |
 |                     |                       |
 |               +-----------+                 |
 |               | HTVECINTC |                 |
 |               +-----------+                 |
 |                ^         ^                  |
 |                |         |                  |
 |          +---------+ +---------+            |
 |          | PCH-PIC | | PCH-MSI |            |
 |          +---------+ +---------+            |
 |            ^     ^           ^              |
 |            |     |           |              |
 |    +---------+ +---------+ +---------+      |
 |    | PCH-LPC | | Devices | | Devices |      |
 |    +---------+ +---------+ +---------+      |
 |         ^                                   |
 |         |                                   |
 |    +---------+                              |
 |    | Devices |                              |
 |    +---------+                              |
 |                                             |
 |                                             |
 +---------------------------------------------+

Extended IRQ model:

In this model, the IPI (Inter-Processor Interrupt) and CPU Local Timer
interrupt go to CPUINTC directly, CPU UARTS interrupts go to LIOINTC,
while all other devices interrupts go to PCH-PIC/PCH-LPC/PCH-MSI and
gathered by EIOINTC, and then go to to CPUINTC directly.

 +--------------------------------------------------------+
 |                                                        |
 |         +-----+     +---------+     +-------+          |
 |         | IPI | --> | CPUINTC | <-- | Timer |          |
 |         +-----+     +---------+     +-------+          |
 |                      ^       ^                         |
 |                      |       |                         |
 |               +---------+ +---------+     +-------+    |
 |               | EIOINTC | | LIOINTC | <-- | UARTs |    |
 |               +---------+ +---------+     +-------+    |
 |                ^       ^                               |
 |                |       |                               |
 |         +---------+ +---------+                        |
 |         | PCH-PIC | | PCH-MSI |                        |
 |         +---------+ +---------+                        |
 |           ^     ^           ^                          |
 |           |     |           |                          |
 |   +---------+ +---------+ +---------+                  |
 |   | PCH-LPC | | Devices | | Devices |                  |
 |   +---------+ +---------+ +---------+                  |
 |        ^                                               |
 |        |                                               |
 |   +---------+                                          |
 |   | Devices |                                          |
 |   +---------+                                          |
 |                                                        |
 |                                                        |
 +--------------------------------------------------------+

The hierarchy model is constructed by parsing irq contronler structures
in MADT. Some controllers((e.g. LIOINTC, HTVECINTC, EIOINTC and PCH-LPC)
are hardcodingly connected to their parents, so their irqdomins are
separately routed to their parents in a fixed way. Some controllers
(e.g. PCH-PIC and PCH-MSI) could be routed to different parents for different
CPU. The firmware will config EIOINTC for the newer CPU and config HTVECINTC
for old CPU in MADT. By this way, PCH-PIC and PCH-MSI irqdomain can only be
routed one parent irqdomin: HTVECINTC or EIOINTC.

Cross-compile tool chain to build kernel:
https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20211202-cross-tools.tar.xz

A CLFS-based Linux distro:
https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-system-2021-12-02.tar.bz2

Loongson and LoongArch documentations:
https://github.com/loongson/LoongArch-Documentation


V1 -> V2:
1, Remove queued patches;
2, Move common logic of DT/ACPI probing to common functions;
3, Split .suspend()/.resume() functions to separate patches.

V2 -> V3:
1, Fix a bug for loongson-pch-pic probe;
2, Some minor improvements for LPC controller.

V3 -> V4:
1, Rework the CPU interrupt controller driver;
2, Some minor improvements for other controllers.

V4 -> V5:
1, Add a description of LoonArch's IRQ model;
2, Support multiple EIOINTCs in one system;
3, Some minor improvements for other controllers.

V5 -> V6:
1, Attach a fwnode to CPUINTC irq domain;
2, Use raw spinlock instead of generic spinlock;
3, Improve the method of restoring EIOINTC state;
4, Update documentation, comments and commit messages.

V6 -> V7:
1, Fix build warnings reported by kernel test robot.

V7 -> V8:
1, Add arguments sanity checking for irqchip init functions;
2, Support Loongson-3C5000 (One NUMA Node includes 4 EIOINTC Node).

V8 -> V9:
1, Rebase on 5.17-rc5;
2, Update cover letter;
3, Some small improvements.

V9 -> V10:
1, Rebase on 5.17-rc6;
2, Fix build warnings reported by kernel test robot.

V10 -> V11:
1, Rebase on 5.18-rc4;
2, Fix irq affinity setting for EIOINTC;
3, Fix hwirq allocation failure for EIOINTC.

V11 -> RFC:
1, Refactored the way to build irqchip hierarchy topology.

Huacai Chen (1):
  irqchip: Adjust Kconfig for Loongson

Jianmin Lv (9):
  irqchip: Add LoongArch CPU interrupt controller support
  irqchip/loongson-pch-pic: Add ACPI init support
  irqchip/loongson-pch-pic: Add suspend/resume support
  irqchip/loongson-pch-msi: Add ACPI init support
  irqchip/loongson-htvec: Add ACPI init support
  irqchip/loongson-htvec: Add suspend/resume support
  irqchip/loongson-liointc: Add ACPI init support
  irqchip: Add Loongson Extended I/O interrupt controller  support
  irqchip: Add Loongson PCH LPC controller support

 drivers/irqchip/Kconfig                    |  38 ++-
 drivers/irqchip/Makefile                   |   3 +
 drivers/irqchip/irq-loongarch-cpu.c        | 134 ++++++++++
 drivers/irqchip/irq-loongarch-pic-common.c |  66 +++++
 drivers/irqchip/irq-loongarch-pic-common.h |  22 ++
 drivers/irqchip/irq-loongson-eiointc.c     | 381 +++++++++++++++++++++++++++++
 drivers/irqchip/irq-loongson-htvec.c       | 148 ++++++++---
 drivers/irqchip/irq-loongson-liointc.c     | 215 ++++++++++------
 drivers/irqchip/irq-loongson-pch-lpc.c     | 225 +++++++++++++++++
 drivers/irqchip/irq-loongson-pch-msi.c     | 138 +++++++----
 drivers/irqchip/irq-loongson-pch-pic.c     | 214 ++++++++++++++--
 include/linux/cpuhotplug.h                 |   1 +
 12 files changed, 1398 insertions(+), 187 deletions(-)
 create mode 100644 drivers/irqchip/irq-loongarch-cpu.c
 create mode 100644 drivers/irqchip/irq-loongarch-pic-common.c
 create mode 100644 drivers/irqchip/irq-loongarch-pic-common.h
 create mode 100644 drivers/irqchip/irq-loongson-eiointc.c
 create mode 100644 drivers/irqchip/irq-loongson-pch-lpc.c

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH RFC 01/10] irqchip: Adjust Kconfig for Loongson
  2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
@ 2022-05-15  3:37 ` Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 02/10] irqchip: Add LoongArch CPU interrupt controller support Jianmin Lv
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-15  3:37 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen,
	Jianmin Lv

From: Huacai Chen <chenhuacai@loongson.cn>

We are preparing to add new Loongson (based on LoongArch, not compatible
with old MIPS-based Loongson) support. HTVEC will be shared by both old
and new Loongson processors, so we adjust its description. HTPIC is only
used by MIPS-based Loongson, so we add a MIPS dependency. PCH_PIC and
PCH_MSI will have some arch-specific code, so we remove the COMPILE_TEST
dependency to avoid build warnings.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
---
 drivers/irqchip/Kconfig | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 15edb9a..39d6be2 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -556,7 +556,7 @@ config LOONGSON_LIOINTC
 
 config LOONGSON_HTPIC
 	bool "Loongson3 HyperTransport PIC Controller"
-	depends on MACH_LOONGSON64
+	depends on (MACH_LOONGSON64 && MIPS)
 	default y
 	select IRQ_DOMAIN
 	select GENERIC_IRQ_CHIP
@@ -564,16 +564,16 @@ config LOONGSON_HTPIC
 	  Support for the Loongson-3 HyperTransport PIC Controller.
 
 config LOONGSON_HTVEC
-	bool "Loongson3 HyperTransport Interrupt Vector Controller"
+	bool "Loongson HyperTransport Interrupt Vector Controller"
 	depends on MACH_LOONGSON64
 	default MACH_LOONGSON64
 	select IRQ_DOMAIN_HIERARCHY
 	help
-	  Support for the Loongson3 HyperTransport Interrupt Vector Controller.
+	  Support for the Loongson HyperTransport Interrupt Vector Controller.
 
 config LOONGSON_PCH_PIC
 	bool "Loongson PCH PIC Controller"
-	depends on MACH_LOONGSON64 || COMPILE_TEST
+	depends on MACH_LOONGSON64
 	default MACH_LOONGSON64
 	select IRQ_DOMAIN_HIERARCHY
 	select IRQ_FASTEOI_HIERARCHY_HANDLERS
@@ -582,7 +582,7 @@ config LOONGSON_PCH_PIC
 
 config LOONGSON_PCH_MSI
 	bool "Loongson PCH MSI Controller"
-	depends on MACH_LOONGSON64 || COMPILE_TEST
+	depends on MACH_LOONGSON64
 	depends on PCI
 	default MACH_LOONGSON64
 	select IRQ_DOMAIN_HIERARCHY
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH RFC 02/10] irqchip: Add LoongArch CPU interrupt controller support
  2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 01/10] irqchip: Adjust Kconfig for Loongson Jianmin Lv
@ 2022-05-15  3:37 ` Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 03/10] irqchip/loongson-pch-pic: Add ACPI init support Jianmin Lv
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-15  3:37 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen,
	Jianmin Lv

We are preparing to add new Loongson (based on LoongArch, not compatible
with old MIPS-based Loongson) support. This patch add the LoongArch CPU
interrupt controller support.

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.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
---
 drivers/irqchip/Kconfig                    |  10 +++
 drivers/irqchip/Makefile                   |   1 +
 drivers/irqchip/irq-loongarch-cpu.c        | 134 +++++++++++++++++++++++++++++
 drivers/irqchip/irq-loongarch-pic-common.c |  66 ++++++++++++++
 drivers/irqchip/irq-loongarch-pic-common.h |  22 +++++
 5 files changed, 233 insertions(+)
 create mode 100644 drivers/irqchip/irq-loongarch-cpu.c
 create mode 100644 drivers/irqchip/irq-loongarch-pic-common.c
 create mode 100644 drivers/irqchip/irq-loongarch-pic-common.h

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 39d6be2..a596ee7 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -545,6 +545,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 160a1d8..736f030 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -105,6 +105,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 irq-loongarch-pic-common.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..b1f12f5
--- /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",
+	.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);
+	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);
+
+	return irq_domain;
+}
+#ifdef CONFIG_ACPI
+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);
+#endif
diff --git a/drivers/irqchip/irq-loongarch-pic-common.c b/drivers/irqchip/irq-loongarch-pic-common.c
new file mode 100644
index 0000000..1be544a
--- /dev/null
+++ b/drivers/irqchip/irq-loongarch-pic-common.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Loongson Limited, All Rights Reserved.
+ */
+
+#include <linux/irq.h>
+#include <linux/acpi.h>
+#include "irq-loongarch-pic-common.h"
+
+static struct acpi_vector_group vector_group[MAX_IO_PICS];
+
+static int pci_mcfg_parse(struct acpi_table_header *header)
+{
+	struct acpi_table_mcfg *mcfg;
+	struct acpi_mcfg_allocation *mptr;
+	int i, n;
+
+	if (header->length < sizeof(struct acpi_table_mcfg))
+		return -EINVAL;
+
+	n = (header->length - sizeof(struct acpi_table_mcfg)) /
+					sizeof(struct acpi_mcfg_allocation);
+	mcfg = (struct acpi_table_mcfg *)header;
+	mptr = (struct acpi_mcfg_allocation *) &mcfg[1];
+
+	for (i = 0; i < n; i++, mptr++)
+		vector_group[mptr->pci_segment].node = (mptr->address >> 44) & 0xf;
+
+	return 0;
+}
+
+void __init init_vector_parent_group(void)
+{
+	acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse);
+}
+
+void acpi_set_vector_parent(int node, struct irq_domain *parent)
+{
+	int i;
+
+	if (cpu_has_flatmode)
+		node = cpu_to_node(node * CORES_PER_EIO_NODE);
+
+	for (i = 0; i < MAX_IO_PICS; i++) {
+		if (node == vector_group[i].node) {
+			vector_group[i].parent = parent;
+			return;
+		}
+	}
+}
+
+struct irq_domain *acpi_get_msi_parent(int index)
+{
+	return vector_group[index].parent;
+}
+
+struct irq_domain *acpi_get_pch_parent(int node)
+{
+	int i;
+
+	for (i = 0; i < MAX_IO_PICS; i++) {
+		if (node == vector_group[i].node)
+			return vector_group[i].parent;
+	}
+	return NULL;
+}
diff --git a/drivers/irqchip/irq-loongarch-pic-common.h b/drivers/irqchip/irq-loongarch-pic-common.h
new file mode 100644
index 0000000..1844776
--- /dev/null
+++ b/drivers/irqchip/irq-loongarch-pic-common.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 Loongson Limited, All Rights Reserved.
+ */
+
+#ifndef _IRQ_LOONGARCH_PIC_COMMON_H
+#define _IRQ_LOONGARCH_PIC_COMMON_H
+
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+
+struct acpi_vector_group {
+	int node;
+	struct irq_domain *parent;
+};
+
+void init_vector_parent_group(void);
+void acpi_set_vector_parent(int node, struct irq_domain *parent);
+struct irq_domain *acpi_get_msi_parent(int index);
+struct irq_domain *acpi_get_pch_parent(int node);
+
+#endif /* _IRQ_LOONGARCH_PIC_COMMON_H */
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH RFC 03/10] irqchip/loongson-pch-pic: Add ACPI init support
  2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 01/10] irqchip: Adjust Kconfig for Loongson Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 02/10] irqchip: Add LoongArch CPU interrupt controller support Jianmin Lv
@ 2022-05-15  3:37 ` Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 04/10] irqchip/loongson-pch-pic: Add suspend/resume support Jianmin Lv
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-15  3:37 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen,
	Jianmin Lv

We are preparing to add new Loongson (based on LoongArch, not compatible
with old MIPS-based Loongson) support. LoongArch use ACPI other than DT
as its boot protocol, so add ACPI init support.

PCH-PIC/PCH-MSI stands for "Interrupt Controller" that described in
Section 5 of "Loongson 7A1000 Bridge User Manual". For more information
please refer Documentation/loongarch/irq-chip-model.rst.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
---
 drivers/irqchip/irq-loongson-pch-pic.c | 167 +++++++++++++++++++++++++++------
 1 file changed, 140 insertions(+), 27 deletions(-)

diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c
index a4eb8a2..e374939 100644
--- a/drivers/irqchip/irq-loongson-pch-pic.c
+++ b/drivers/irqchip/irq-loongson-pch-pic.c
@@ -15,6 +15,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include "irq-loongarch-pic-common.h"
 
 /* Registers */
 #define PCH_PIC_MASK		0x20
@@ -33,13 +34,20 @@
 #define PIC_REG_IDX(irq_id)	((irq_id) / PIC_COUNT_PER_REG)
 #define PIC_REG_BIT(irq_id)	((irq_id) % PIC_COUNT_PER_REG)
 
+static int nr_pics;
+
 struct pch_pic {
 	void __iomem		*base;
 	struct irq_domain	*pic_domain;
+	struct fwnode_handle	*domain_handle;
 	u32			ht_vec_base;
 	raw_spinlock_t		pic_lock;
+	u32			gsi_end;
+	u32			gsi_base;
 };
 
+static struct pch_pic *pch_pic_priv[2];
+
 static void pch_pic_bitset(struct pch_pic *priv, int offset, int bit)
 {
 	u32 reg;
@@ -180,7 +188,7 @@ static void pch_pic_reset(struct pch_pic *priv)
 	int i;
 
 	for (i = 0; i < PIC_COUNT; i++) {
-		/* Write vectored ID */
+		/* Write vector ID */
 		writeb(priv->ht_vec_base + i, priv->base + PCH_INT_HTVEC(i));
 		/* Hardcode route to HT0 Lo */
 		writeb(1, priv->base + PCH_INT_ROUTE(i));
@@ -198,50 +206,61 @@ static void pch_pic_reset(struct pch_pic *priv)
 	}
 }
 
-static int pch_pic_of_init(struct device_node *node,
-				struct device_node *parent)
+int find_pch_pic(u32 gsi)
 {
+	int i;
+
+	if (nr_pics == 0)
+		return -1;
+
+	/* Find the PCH_PIC that manages this GSI. */
+	for (i = 0; i < nr_pics; i++) {
+		if (gsi >= pch_pic_priv[i]->gsi_base && gsi <= pch_pic_priv[i]->gsi_end)
+			return i;
+	}
+
+	printk(KERN_ERR "ERROR: Unable to locate PCH_PIC for GSI %d\n", gsi);
+	return -1;
+}
+
+static int pch_pic_init(phys_addr_t addr, unsigned long size, int vec_base,
+			struct irq_domain *parent_domain, struct fwnode_handle *domain_handle,
+			u32 gsi_base)
+{
+	int vec_count;
 	struct pch_pic *priv;
-	struct irq_domain *parent_domain;
-	int err;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	raw_spin_lock_init(&priv->pic_lock);
-	priv->base = of_iomap(node, 0);
-	if (!priv->base) {
-		err = -ENOMEM;
+	priv->base = ioremap(addr, size);
+	if (!priv->base)
 		goto free_priv;
-	}
 
-	parent_domain = irq_find_host(parent);
-	if (!parent_domain) {
-		pr_err("Failed to find the parent domain\n");
-		err = -ENXIO;
-		goto iounmap_base;
-	}
+	priv->domain_handle = domain_handle;
 
-	if (of_property_read_u32(node, "loongson,pic-base-vec",
-				&priv->ht_vec_base)) {
-		pr_err("Failed to determine pic-base-vec\n");
-		err = -EINVAL;
-		goto iounmap_base;
-	}
+	priv->ht_vec_base = vec_base;
+	vec_count = ((readq(priv->base) >> 48) & 0xff) + 1;
+	priv->gsi_base = gsi_base;
+	priv->gsi_end = gsi_base + vec_count - 1;
 
 	priv->pic_domain = irq_domain_create_hierarchy(parent_domain, 0,
-						       PIC_COUNT,
-						       of_node_to_fwnode(node),
-						       &pch_pic_domain_ops,
-						       priv);
+						vec_count, priv->domain_handle,
+						&pch_pic_domain_ops, priv);
+
 	if (!priv->pic_domain) {
 		pr_err("Failed to create IRQ domain\n");
-		err = -ENOMEM;
 		goto iounmap_base;
 	}
 
 	pch_pic_reset(priv);
+	pch_pic_domain[nr_pics] = priv->pic_domain;
+	pch_pic_priv[nr_pics++] = priv;
+	register_syscore_ops(&pch_pic_syscore_ops);
+
+	register_syscore_ops(&pch_pic_syscore_ops);
 
 	return 0;
 
@@ -250,7 +269,101 @@ static int pch_pic_of_init(struct device_node *node,
 free_priv:
 	kfree(priv);
 
-	return err;
+	return -EINVAL;
+}
+
+#ifdef CONFIG_OF
+
+static int pch_pic_of_init(struct device_node *node,
+				struct device_node *parent)
+{
+	int err, vec_base;
+	struct resource res;
+	struct irq_domain *parent_domain;
+
+	if (of_address_to_resource(node, 0, &res))
+		return -EINVAL;
+
+	parent_domain = irq_find_host(parent);
+	if (!parent_domain) {
+		pr_err("Failed to find the parent domain\n");
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(node, "loongson,pic-base-vec", &vec_base)) {
+		pr_err("Failed to determine pic-base-vec\n");
+		return -EINVAL;
+	}
+
+	err = pch_pic_init(res.start, resource_size(&res), vec_base,
+				parent_domain, of_node_to_fwnode(node), 0);
+	if (err < 0)
+		return err;
+
+	return 0;
 }
 
 IRQCHIP_DECLARE(pch_pic, "loongson,pch-pic-1.0", pch_pic_of_init);
+
+#endif
+
+#ifdef CONFIG_ACPI
+static int __init
+lpcintc_parse_madt(union acpi_subtable_headers *header,
+		       const unsigned long end)
+{
+	struct acpi_madt_lpc_pic *lpcintc_entry = (struct acpi_madt_lpc_pic *)header;
+
+	return pch_lpc_acpi_init(pch_pic_priv[0]->pic_domain, lpcintc_entry);
+}
+
+static int __init acpi_cascade_irqdomain_init(void)
+{
+	acpi_table_parse_madt(ACPI_MADT_TYPE_LPC_PIC,
+			      lpcintc_parse_madt, 0);
+	return 0;
+}
+int __init pch_pic_init_irqdomain(struct irq_domain *parent,
+					struct acpi_madt_bio_pic *acpi_pchpic)
+{
+	int ret, vec_base;
+	struct fwnode_handle *domain_handle;
+
+	if (!acpi_pchpic)
+		return -EINVAL;
+
+	vec_base = acpi_pchpic->gsi_base - GSI_MIN_PCH_IRQ;
+
+	domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_pchpic);
+	if (!domain_handle) {
+		pr_err("Unable to allocate domain handle\n");
+		return -ENOMEM;
+	}
+
+	ret = pch_pic_init(acpi_pchpic->address, acpi_pchpic->size,
+				vec_base, parent, domain_handle, acpi_pchpic->gsi_base);
+	if (ret == 0 && acpi_pchpic->id == 0)
+		acpi_cascade_irqdomain_init();
+
+	return ret;
+}
+
+static int __init pchintc_parse_madt(union acpi_subtable_headers *header,
+		       const unsigned long end)
+{
+	struct acpi_madt_bio_pic *pch_pic_entry = (struct acpi_madt_bio_pic *)header;
+
+	acpi_pchpic[nr_pics] = pch_pic_entry;
+	return pch_pic_init_irqdomain(acpi_get_pch_parent((pch_pic_entry->address >> 44) & 0xf),
+										pch_pic_entry);
+}
+
+static int __init pch_pic_acpi_init(void)
+{
+	acpi_table_parse_madt(ACPI_MADT_TYPE_BIO_PIC,
+			      pchintc_parse_madt, 0);
+
+	return 0;
+}
+early_initcall(pch_pic_acpi_init);
+#endif
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH RFC 04/10] irqchip/loongson-pch-pic: Add suspend/resume support
  2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
                   ` (2 preceding siblings ...)
  2022-05-15  3:37 ` [PATCH RFC 03/10] irqchip/loongson-pch-pic: Add ACPI init support Jianmin Lv
@ 2022-05-15  3:37 ` Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 05/10] irqchip/loongson-pch-msi: Add ACPI init support Jianmin Lv
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-15  3:37 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen,
	Jianmin Lv

Add suspend/resume support for PCH-PIC irqchip, which is needed for
suspend/hibernation.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
---
 drivers/irqchip/irq-loongson-pch-pic.c | 47 ++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c
index e374939..37b9459 100644
--- a/drivers/irqchip/irq-loongson-pch-pic.c
+++ b/drivers/irqchip/irq-loongson-pch-pic.c
@@ -15,6 +15,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/syscore_ops.h>
 #include "irq-loongarch-pic-common.h"
 
 /* Registers */
@@ -42,6 +43,9 @@ struct pch_pic {
 	struct fwnode_handle	*domain_handle;
 	u32			ht_vec_base;
 	raw_spinlock_t		pic_lock;
+	u32			saved_vec_en[PIC_REG_COUNT];
+	u32			saved_vec_pol[PIC_REG_COUNT];
+	u32			saved_vec_edge[PIC_REG_COUNT];
 	u32			gsi_end;
 	u32			gsi_base;
 };
@@ -145,6 +149,7 @@ static void pch_pic_ack_irq(struct irq_data *d)
 	.irq_ack		= pch_pic_ack_irq,
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 	.irq_set_type		= pch_pic_set_type,
+	.flags			= IRQCHIP_SKIP_SET_WAKE,
 };
 
 static int pch_pic_alloc(struct irq_domain *domain, unsigned int virq,
@@ -223,6 +228,46 @@ int find_pch_pic(u32 gsi)
 	return -1;
 }
 
+static int pch_pic_suspend(void)
+{
+	int i, j;
+
+	for (i = 0; i < nr_pics; i++) {
+		for (j = 0; j < PIC_REG_COUNT; j++) {
+			pch_pic_priv[i]->saved_vec_pol[j] =
+				readl(pch_pic_priv[i]->base + PCH_PIC_POL + 4 * j);
+			pch_pic_priv[i]->saved_vec_edge[j] =
+				readl(pch_pic_priv[i]->base + PCH_PIC_EDGE + 4 * j);
+			pch_pic_priv[i]->saved_vec_en[j] =
+				readl(pch_pic_priv[i]->base + PCH_PIC_MASK + 4 * j);
+		}
+	}
+
+	return 0;
+}
+
+static void pch_pic_resume(void)
+{
+	int i, j;
+
+	for (i = 0; i < nr_pics; i++) {
+		pch_pic_reset(pch_pic_priv[i]);
+		for (j = 0; j < PIC_REG_COUNT; j++) {
+			writel(pch_pic_priv[i]->saved_vec_pol[j],
+					pch_pic_priv[i]->base + PCH_PIC_POL + 4 * j);
+			writel(pch_pic_priv[i]->saved_vec_edge[j],
+					pch_pic_priv[i]->base + PCH_PIC_EDGE + 4 * j);
+			writel(pch_pic_priv[i]->saved_vec_en[j],
+					pch_pic_priv[i]->base + PCH_PIC_MASK + 4 * j);
+		}
+	}
+}
+
+static struct syscore_ops pch_pic_syscore_ops = {
+	.suspend =  pch_pic_suspend,
+	.resume =  pch_pic_resume,
+};
+
 static int pch_pic_init(phys_addr_t addr, unsigned long size, int vec_base,
 			struct irq_domain *parent_domain, struct fwnode_handle *domain_handle,
 			u32 gsi_base)
@@ -262,6 +307,8 @@ static int pch_pic_init(phys_addr_t addr, unsigned long size, int vec_base,
 
 	register_syscore_ops(&pch_pic_syscore_ops);
 
+	register_syscore_ops(&pch_pic_syscore_ops);
+
 	return 0;
 
 iounmap_base:
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH RFC 05/10] irqchip/loongson-pch-msi: Add ACPI init support
  2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
                   ` (3 preceding siblings ...)
  2022-05-15  3:37 ` [PATCH RFC 04/10] irqchip/loongson-pch-pic: Add suspend/resume support Jianmin Lv
@ 2022-05-15  3:37 ` Jianmin Lv
  2022-05-15  3:37 ` [PATCH RFC 06/10] irqchip/loongson-htvec: " Jianmin Lv
  2022-05-16 13:13 ` [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
  6 siblings, 0 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-15  3:37 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen,
	Jianmin Lv

We are preparing to add new Loongson (based on LoongArch, not compatible
with old MIPS-based Loongson) support. LoongArch use ACPI other than DT
as its boot protocol, so add ACPI init support.

PCH-PIC/PCH-MSI stands for "Interrupt Controller" that described in
Section 5 of "Loongson 7A1000 Bridge User Manual". For more information
please refer Documentation/loongarch/irq-chip-model.rst.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
---
 drivers/irqchip/irq-loongson-pch-msi.c | 138 +++++++++++++++++++++++----------
 1 file changed, 96 insertions(+), 42 deletions(-)

diff --git a/drivers/irqchip/irq-loongson-pch-msi.c b/drivers/irqchip/irq-loongson-pch-msi.c
index e3801c4..eed3c2e 100644
--- a/drivers/irqchip/irq-loongson-pch-msi.c
+++ b/drivers/irqchip/irq-loongson-pch-msi.c
@@ -14,6 +14,9 @@
 #include <linux/of_pci.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include "irq-loongarch-pic-common.h"
+
+static int nr_pics;
 
 struct pch_msi_data {
 	struct mutex	msi_map_lock;
@@ -21,8 +24,11 @@ struct pch_msi_data {
 	u32		irq_first;	/* The vector number that MSIs starts */
 	u32		num_irqs;	/* The number of vectors for MSIs */
 	unsigned long	*msi_map;
+	struct fwnode_handle *domain_handle;
 };
 
+static struct pch_msi_data *pch_msi_priv[2];
+
 static void pch_msi_mask_msi_irq(struct irq_data *d)
 {
 	pci_msi_mask_irq(d);
@@ -154,12 +160,14 @@ static void pch_msi_middle_domain_free(struct irq_domain *domain,
 };
 
 static int pch_msi_init_domains(struct pch_msi_data *priv,
-				struct device_node *node,
-				struct irq_domain *parent)
+				struct irq_domain *parent,
+				struct fwnode_handle *domain_handle)
 {
 	struct irq_domain *middle_domain, *msi_domain;
 
-	middle_domain = irq_domain_create_linear(of_node_to_fwnode(node),
+	priv->domain_handle = domain_handle;
+
+	middle_domain = irq_domain_create_linear(priv->domain_handle,
 						priv->num_irqs,
 						&pch_msi_middle_domain_ops,
 						priv);
@@ -171,7 +179,7 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
 	middle_domain->parent = parent;
 	irq_domain_update_bus_token(middle_domain, DOMAIN_BUS_NEXUS);
 
-	msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node),
+	msi_domain = pci_msi_create_irq_domain(priv->domain_handle,
 					       &pch_msi_domain_info,
 					       middle_domain);
 	if (!msi_domain) {
@@ -183,19 +191,11 @@ static int pch_msi_init_domains(struct pch_msi_data *priv,
 	return 0;
 }
 
-static int pch_msi_init(struct device_node *node,
-			    struct device_node *parent)
+static int pch_msi_init(phys_addr_t msg_address, int irq_base, int irq_count,
+			struct irq_domain *parent_domain, struct fwnode_handle *domain_handle)
 {
-	struct pch_msi_data *priv;
-	struct irq_domain *parent_domain;
-	struct resource res;
 	int ret;
-
-	parent_domain = irq_find_host(parent);
-	if (!parent_domain) {
-		pr_err("Failed to find the parent domain\n");
-		return -ENXIO;
-	}
+	struct pch_msi_data *priv;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -203,48 +203,102 @@ static int pch_msi_init(struct device_node *node,
 
 	mutex_init(&priv->msi_map_lock);
 
-	ret = of_address_to_resource(node, 0, &res);
-	if (ret) {
-		pr_err("Failed to allocate resource\n");
-		goto err_priv;
-	}
-
-	priv->doorbell = res.start;
-
-	if (of_property_read_u32(node, "loongson,msi-base-vec",
-				&priv->irq_first)) {
-		pr_err("Unable to parse MSI vec base\n");
-		ret = -EINVAL;
-		goto err_priv;
-	}
-
-	if (of_property_read_u32(node, "loongson,msi-num-vecs",
-				&priv->num_irqs)) {
-		pr_err("Unable to parse MSI vec number\n");
-		ret = -EINVAL;
-		goto err_priv;
-	}
+	priv->doorbell = msg_address;
+	priv->irq_first = irq_base;
+	priv->num_irqs = irq_count;
 
 	priv->msi_map = bitmap_zalloc(priv->num_irqs, GFP_KERNEL);
-	if (!priv->msi_map) {
-		ret = -ENOMEM;
+	if (!priv->msi_map)
 		goto err_priv;
-	}
 
 	pr_debug("Registering %d MSIs, starting at %d\n",
 		 priv->num_irqs, priv->irq_first);
 
-	ret = pch_msi_init_domains(priv, node, parent_domain);
+	ret = pch_msi_init_domains(priv, parent_domain, domain_handle);
 	if (ret)
 		goto err_map;
 
+	pch_msi_domain[nr_pics] = irq_find_matching_fwnode(domain_handle, DOMAIN_BUS_PCI_MSI);
+	pch_msi_priv[nr_pics++] = priv;
 	return 0;
 
 err_map:
 	bitmap_free(priv->msi_map);
 err_priv:
 	kfree(priv);
-	return ret;
+
+	return -EINVAL;
+}
+
+#ifdef CONFIG_OF
+
+static int pch_msi_of_init(struct device_node *node, struct device_node *parent)
+{
+	int err;
+	int irq_base, irq_count;
+	struct resource res;
+	struct irq_domain *parent_domain;
+
+	parent_domain = irq_find_host(parent);
+	if (!parent_domain) {
+		pr_err("Failed to find the parent domain\n");
+		return -ENXIO;
+	}
+
+	if (of_address_to_resource(node, 0, &res)) {
+		pr_err("Failed to allocate resource\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(node, "loongson,msi-base-vec", &irq_base)) {
+		pr_err("Unable to parse MSI vec base\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(node, "loongson,msi-num-vecs", &irq_count)) {
+		pr_err("Unable to parse MSI vec number\n");
+		return -EINVAL;
+	}
+
+	err = pch_msi_init(res.start, irq_base, irq_count, parent_domain, of_node_to_fwnode(node));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(pch_msi, "loongson,pch-msi-1.0", pch_msi_of_init);
+
+#endif
+
+#ifdef CONFIG_ACPI
+int __init pch_msi_init_irqdomain(struct irq_domain *parent,
+					struct acpi_madt_msi_pic *acpi_pchmsi)
+{
+	struct fwnode_handle *domain_handle;
+
+	if (!acpi_pchmsi)
+		return -EINVAL;
+
+	domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_pchmsi);
+
+	return pch_msi_init(acpi_pchmsi->msg_address, acpi_pchmsi->start,
+				acpi_pchmsi->count, parent, domain_handle);
+}
+static int __init msiintc_parse_madt(union acpi_subtable_headers *header,
+		       const unsigned long end)
+{
+	struct acpi_madt_msi_pic *pch_msi_entry = (struct acpi_madt_msi_pic *)header;
+
+	return pch_msi_init_irqdomain(acpi_get_msi_parent(nr_pics), pch_msi_entry);
 }
 
-IRQCHIP_DECLARE(pch_msi, "loongson,pch-msi-1.0", pch_msi_init);
+static int __init pch_msi_acpi_init(void)
+{
+	acpi_table_parse_madt(ACPI_MADT_TYPE_MSI_PIC,
+			      msiintc_parse_madt, 0);
+
+	return 0;
+}
+early_initcall(pch_msi_acpi_init);
+#endif
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH RFC 06/10] irqchip/loongson-htvec: Add ACPI init support
  2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
                   ` (4 preceding siblings ...)
  2022-05-15  3:37 ` [PATCH RFC 05/10] irqchip/loongson-pch-msi: Add ACPI init support Jianmin Lv
@ 2022-05-15  3:37 ` Jianmin Lv
  2022-05-16 13:13 ` [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
  6 siblings, 0 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-15  3:37 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen,
	Jianmin Lv

We are preparing to add new Loongson (based on LoongArch, not compatible
with old MIPS-based Loongson) support. LoongArch use ACPI other than DT
as its boot protocol, so add ACPI init support.

HTVECINTC stands for "HyperTransport Interrupts" that described in
Section 14.3 of "Loongson 3A5000 Processor Reference Manual". For more
information please refer Documentation/loongarch/irq-chip-model.rst.

Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn>
---
 drivers/irqchip/irq-loongson-htvec.c | 121 +++++++++++++++++++++++++----------
 1 file changed, 87 insertions(+), 34 deletions(-)

diff --git a/drivers/irqchip/irq-loongson-htvec.c b/drivers/irqchip/irq-loongson-htvec.c
index 60a335d..354630b 100644
--- a/drivers/irqchip/irq-loongson-htvec.c
+++ b/drivers/irqchip/irq-loongson-htvec.c
@@ -16,11 +16,11 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include "irq-loongarch-pic-common.h"
 
 /* Registers */
 #define HTVEC_EN_OFF		0x20
 #define HTVEC_MAX_PARENT_IRQ	8
-
 #define VEC_COUNT_PER_REG	32
 #define VEC_REG_IDX(irq_id)	((irq_id) / VEC_COUNT_PER_REG)
 #define VEC_REG_BIT(irq_id)	((irq_id) % VEC_COUNT_PER_REG)
@@ -30,8 +30,11 @@ struct htvec {
 	void __iomem		*base;
 	struct irq_domain	*htvec_domain;
 	raw_spinlock_t		htvec_lock;
+	struct fwnode_handle	*domain_handle;
 };
 
+static struct htvec *htvec_priv;
+
 static void htvec_irq_dispatch(struct irq_desc *desc)
 {
 	int i;
@@ -155,64 +158,114 @@ static void htvec_reset(struct htvec *priv)
 	}
 }
 
-static int htvec_of_init(struct device_node *node,
-				struct device_node *parent)
+static int htvec_init(phys_addr_t addr, unsigned long size,
+		int num_parents, int parent_irq[], struct fwnode_handle *domain_handle)
 {
+	int i;
 	struct htvec *priv;
-	int err, parent_irq[8], i;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
+	priv->num_parents = num_parents;
+	priv->base = ioremap(addr, size);
+	priv->domain_handle = domain_handle;
 	raw_spin_lock_init(&priv->htvec_lock);
-	priv->base = of_iomap(node, 0);
-	if (!priv->base) {
-		err = -ENOMEM;
-		goto free_priv;
-	}
-
-	/* Interrupt may come from any of the 8 interrupt lines */
-	for (i = 0; i < HTVEC_MAX_PARENT_IRQ; i++) {
-		parent_irq[i] = irq_of_parse_and_map(node, i);
-		if (parent_irq[i] <= 0)
-			break;
-
-		priv->num_parents++;
-	}
 
-	if (!priv->num_parents) {
-		pr_err("Failed to get parent irqs\n");
-		err = -ENODEV;
-		goto iounmap_base;
-	}
-
-	priv->htvec_domain = irq_domain_create_linear(of_node_to_fwnode(node),
+	/* Setup IRQ domain */
+	priv->htvec_domain = irq_domain_create_linear(priv->domain_handle,
 					(VEC_COUNT_PER_REG * priv->num_parents),
 					&htvec_domain_ops, priv);
 	if (!priv->htvec_domain) {
-		pr_err("Failed to create IRQ domain\n");
-		err = -ENOMEM;
-		goto irq_dispose;
+		pr_err("loongson-htvec: cannot add IRQ domain\n");
+		goto iounmap_base;
 	}
 
 	htvec_reset(priv);
 
-	for (i = 0; i < priv->num_parents; i++)
+	for (i = 0; i < priv->num_parents; i++) {
 		irq_set_chained_handler_and_data(parent_irq[i],
 						 htvec_irq_dispatch, priv);
+	}
+
+	htvec_priv = priv;
+
+	register_syscore_ops(&htvec_syscore_ops);
 
 	return 0;
 
-irq_dispose:
-	for (; i > 0; i--)
-		irq_dispose_mapping(parent_irq[i - 1]);
 iounmap_base:
 	iounmap(priv->base);
-free_priv:
+	priv->domain_handle = NULL;
 	kfree(priv);
 
-	return err;
+	return -EINVAL;
+}
+
+#ifdef CONFIG_OF
+
+static int htvec_of_init(struct device_node *node,
+				struct device_node *parent)
+{
+	int i, err;
+	int parent_irq[8];
+	int num_parents = 0;
+	struct resource res;
+
+	if (of_address_to_resource(node, 0, &res))
+		return -EINVAL;
+
+	/* Interrupt may come from any of the 8 interrupt lines */
+	for (i = 0; i < HTVEC_MAX_PARENT_IRQ; i++) {
+		parent_irq[i] = irq_of_parse_and_map(node, i);
+		if (parent_irq[i] <= 0)
+			break;
+
+		num_parents++;
+	}
+
+	err = htvec_init(res.start, resource_size(&res),
+			num_parents, parent_irq, of_node_to_fwnode(node));
+	if (err < 0)
+		return err;
+
+	return 0;
 }
 
 IRQCHIP_DECLARE(htvec, "loongson,htvec-1.0", htvec_of_init);
+
+#endif
+
+#ifdef CONFIG_ACPI
+int __init htvec_acpi_init(struct irq_domain *parent,
+				   struct acpi_madt_ht_pic *acpi_htvec)
+{
+	int i, ret;
+	int num_parents, parent_irq[8];
+	struct fwnode_handle *domain_handle;
+
+	if (!acpi_htvec)
+		return -EINVAL;
+
+	num_parents = HTVEC_MAX_PARENT_IRQ;
+
+	domain_handle = irq_domain_alloc_fwnode((phys_addr_t *)acpi_htvec);
+	if (!domain_handle) {
+		pr_err("Unable to allocate domain handle\n");
+		return NULL;
+	}
+
+	/* Interrupt may come from any of the 8 interrupt lines */
+	for (i = 0; i < HTVEC_MAX_PARENT_IRQ; i++)
+		parent_irq[i] = irq_create_mapping(parent, acpi_htvec->cascade[i]);
+
+	ret = htvec_init(acpi_htvec->address, acpi_htvec->size,
+			num_parents, parent_irq, domain_handle);
+	if (ret == 0)
+		acpi_set_vector_parent(0, htvec_priv->htvec_domain);
+
+	return ret;
+}
+
+#endif
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers
  2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
                   ` (5 preceding siblings ...)
  2022-05-15  3:37 ` [PATCH RFC 06/10] irqchip/loongson-htvec: " Jianmin Lv
@ 2022-05-16 13:13 ` Jianmin Lv
  2022-05-18  1:52   ` Jianmin Lv
  6 siblings, 1 reply; 9+ messages in thread
From: Jianmin Lv @ 2022-05-16 13:13 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen

On 2022/5/15 上午11:37, Jianmin Lv wrote:
> LoongArch is a new RISC ISA, which is a bit like MIPS or RISC-V.
> LoongArch includes a reduced 32-bit version (LA32R), a standard 32-bit
> version (LA32S) and a 64-bit version (LA64). LoongArch use ACPI as its
> boot protocol LoongArch-specific interrupt controllers (similar to APIC)
> are already added in the ACPI Specification 6.5(which may be published in
> early June this year and the board is reviewing the draft).
> 
> Currently, LoongArch based processors (e.g. Loongson-3A5000) can only
> work together with LS7A chipsets. The irq chips in LoongArch computers
> include CPUINTC (CPU Core Interrupt Controller), LIOINTC (Legacy I/O
> Interrupt Controller), EIOINTC (Extended I/O Interrupt Controller),
> HTVECINTC (Hyper-Transport Vector Interrupt Controller), PCH-PIC (Main
> Interrupt Controller in LS7A chipset), PCH-LPC (LPC Interrupt Controller
> in LS7A chipset) and PCH-MSI (MSI Interrupt Controller).
> 
> CPUINTC is a per-core controller (in CPU), LIOINTC/EIOINTC/HTVECINTC are
> per-package controllers (in CPU), while PCH-PIC/PCH-LPC/PCH-MSI are all
> controllers out of CPU (i.e., in chipsets). These controllers (in other
> words, irqchips) are linked in a hierarchy, and there are two models of
> hierarchy (legacy model and extended model).
> 
> Legacy IRQ model:
> 
> In this model, the IPI (Inter-Processor Interrupt) and CPU Local Timer
> interrupt go to CPUINTC directly, CPU UARTS interrupts go to LIOINTC,
> while all other devices interrupts go to PCH-PIC/PCH-LPC/PCH-MSI and
> gathered by HTVECINTC, and then go to LIOINTC, and then CPUINTC.
> 
>   +---------------------------------------------+
>   |                                             |
>   |    +-----+     +---------+     +-------+    |
>   |    | IPI | --> | CPUINTC | <-- | Timer |    |
>   |    +-----+     +---------+     +-------+    |
>   |                     ^                       |
>   |                     |                       |
>   |                +---------+     +-------+    |
>   |                | LIOINTC | <-- | UARTs |    |
>   |                +---------+     +-------+    |
>   |                     ^                       |
>   |                     |                       |
>   |               +-----------+                 |
>   |               | HTVECINTC |                 |
>   |               +-----------+                 |
>   |                ^         ^                  |
>   |                |         |                  |
>   |          +---------+ +---------+            |
>   |          | PCH-PIC | | PCH-MSI |            |
>   |          +---------+ +---------+            |
>   |            ^     ^           ^              |
>   |            |     |           |              |
>   |    +---------+ +---------+ +---------+      |
>   |    | PCH-LPC | | Devices | | Devices |      |
>   |    +---------+ +---------+ +---------+      |
>   |         ^                                   |
>   |         |                                   |
>   |    +---------+                              |
>   |    | Devices |                              |
>   |    +---------+                              |
>   |                                             |
>   |                                             |
>   +---------------------------------------------+
> 
> Extended IRQ model:
> 
> In this model, the IPI (Inter-Processor Interrupt) and CPU Local Timer
> interrupt go to CPUINTC directly, CPU UARTS interrupts go to LIOINTC,
> while all other devices interrupts go to PCH-PIC/PCH-LPC/PCH-MSI and
> gathered by EIOINTC, and then go to to CPUINTC directly.
> 
>   +--------------------------------------------------------+
>   |                                                        |
>   |         +-----+     +---------+     +-------+          |
>   |         | IPI | --> | CPUINTC | <-- | Timer |          |
>   |         +-----+     +---------+     +-------+          |
>   |                      ^       ^                         |
>   |                      |       |                         |
>   |               +---------+ +---------+     +-------+    |
>   |               | EIOINTC | | LIOINTC | <-- | UARTs |    |
>   |               +---------+ +---------+     +-------+    |
>   |                ^       ^                               |
>   |                |       |                               |
>   |         +---------+ +---------+                        |
>   |         | PCH-PIC | | PCH-MSI |                        |
>   |         +---------+ +---------+                        |
>   |           ^     ^           ^                          |
>   |           |     |           |                          |
>   |   +---------+ +---------+ +---------+                  |
>   |   | PCH-LPC | | Devices | | Devices |                  |
>   |   +---------+ +---------+ +---------+                  |
>   |        ^                                               |
>   |        |                                               |
>   |   +---------+                                          |
>   |   | Devices |                                          |
>   |   +---------+                                          |
>   |                                                        |
>   |                                                        |
>   +--------------------------------------------------------+
> 
> The hierarchy model is constructed by parsing irq contronler structures
> in MADT. Some controllers((e.g. LIOINTC, HTVECINTC, EIOINTC and PCH-LPC)
> are hardcodingly connected to their parents, so their irqdomins are
> separately routed to their parents in a fixed way. Some controllers
> (e.g. PCH-PIC and PCH-MSI) could be routed to different parents for different
> CPU. The firmware will config EIOINTC for the newer CPU and config HTVECINTC
> for old CPU in MADT. By this way, PCH-PIC and PCH-MSI irqdomain can only be
> routed one parent irqdomin: HTVECINTC or EIOINTC.
> 
> Cross-compile tool chain to build kernel:
> https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20211202-cross-tools.tar.xz
> 
> A CLFS-based Linux distro:
> https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-system-2021-12-02.tar.bz2
> 
> Loongson and LoongArch documentations:
> https://github.com/loongson/LoongArch-Documentation
> 
> 
> V1 -> V2:
> 1, Remove queued patches;
> 2, Move common logic of DT/ACPI probing to common functions;
> 3, Split .suspend()/.resume() functions to separate patches.
> 
> V2 -> V3:
> 1, Fix a bug for loongson-pch-pic probe;
> 2, Some minor improvements for LPC controller.
> 
> V3 -> V4:
> 1, Rework the CPU interrupt controller driver;
> 2, Some minor improvements for other controllers.
> 
> V4 -> V5:
> 1, Add a description of LoonArch's IRQ model;
> 2, Support multiple EIOINTCs in one system;
> 3, Some minor improvements for other controllers.
> 
> V5 -> V6:
> 1, Attach a fwnode to CPUINTC irq domain;
> 2, Use raw spinlock instead of generic spinlock;
> 3, Improve the method of restoring EIOINTC state;
> 4, Update documentation, comments and commit messages.
> 
> V6 -> V7:
> 1, Fix build warnings reported by kernel test robot.
> 
> V7 -> V8:
> 1, Add arguments sanity checking for irqchip init functions;
> 2, Support Loongson-3C5000 (One NUMA Node includes 4 EIOINTC Node).
> 
> V8 -> V9:
> 1, Rebase on 5.17-rc5;
> 2, Update cover letter;
> 3, Some small improvements.
> 
> V9 -> V10:
> 1, Rebase on 5.17-rc6;
> 2, Fix build warnings reported by kernel test robot.
> 
> V10 -> V11:
> 1, Rebase on 5.18-rc4;
> 2, Fix irq affinity setting for EIOINTC;
> 3, Fix hwirq allocation failure for EIOINTC.
> 
> V11 -> RFC:
> 1, Refactored the way to build irqchip hierarchy topology.
> 

Hi, Marc

The irqchip topology building is refactored as following way in this RFC 
patches according to my reply in V10, please help to review them if they 
are correct, thanks very much!

- Only call irqchip_init() in arch file.
- Use IRQCHIP_ACPI_DECLARE to declare entry of CORE PIC.
- Initialize irqdomains in fixed way from their parent irqdomain for 
hardcodingly routing irqchips(liointc, htvec, eiointc and pch-lpc) in 
hardware.
- Initialize irqdomains in scaled way for scalable routing 
irqchips(pch-pic and pch-msi).
- For eiointc and htvec, they are exclusive, and only one kind of them 
can be configured in MADT.

> Huacai Chen (1):
>    irqchip: Adjust Kconfig for Loongson
> 
> Jianmin Lv (9):
>    irqchip: Add LoongArch CPU interrupt controller support
>    irqchip/loongson-pch-pic: Add ACPI init support
>    irqchip/loongson-pch-pic: Add suspend/resume support
>    irqchip/loongson-pch-msi: Add ACPI init support
>    irqchip/loongson-htvec: Add ACPI init support
>    irqchip/loongson-htvec: Add suspend/resume support
>    irqchip/loongson-liointc: Add ACPI init support
>    irqchip: Add Loongson Extended I/O interrupt controller  support
>    irqchip: Add Loongson PCH LPC controller support
> 
>   drivers/irqchip/Kconfig                    |  38 ++-
>   drivers/irqchip/Makefile                   |   3 +
>   drivers/irqchip/irq-loongarch-cpu.c        | 134 ++++++++++
>   drivers/irqchip/irq-loongarch-pic-common.c |  66 +++++
>   drivers/irqchip/irq-loongarch-pic-common.h |  22 ++
>   drivers/irqchip/irq-loongson-eiointc.c     | 381 +++++++++++++++++++++++++++++
>   drivers/irqchip/irq-loongson-htvec.c       | 148 ++++++++---
>   drivers/irqchip/irq-loongson-liointc.c     | 215 ++++++++++------
>   drivers/irqchip/irq-loongson-pch-lpc.c     | 225 +++++++++++++++++
>   drivers/irqchip/irq-loongson-pch-msi.c     | 138 +++++++----
>   drivers/irqchip/irq-loongson-pch-pic.c     | 214 ++++++++++++++--
>   include/linux/cpuhotplug.h                 |   1 +
>   12 files changed, 1398 insertions(+), 187 deletions(-)
>   create mode 100644 drivers/irqchip/irq-loongarch-cpu.c
>   create mode 100644 drivers/irqchip/irq-loongarch-pic-common.c
>   create mode 100644 drivers/irqchip/irq-loongarch-pic-common.h
>   create mode 100644 drivers/irqchip/irq-loongson-eiointc.c
>   create mode 100644 drivers/irqchip/irq-loongson-pch-lpc.c
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers
  2022-05-16 13:13 ` [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
@ 2022-05-18  1:52   ` Jianmin Lv
  0 siblings, 0 replies; 9+ messages in thread
From: Jianmin Lv @ 2022-05-18  1:52 UTC (permalink / raw)
  To: Thomas Gleixner, Marc Zyngier
  Cc: linux-kernel, Xuefeng Li, Huacai Chen, Jiaxun Yang, Huacai Chen

On 2022/5/16 下午9:13, Jianmin Lv wrote:
> On 2022/5/15 上午11:37, Jianmin Lv wrote:
>> LoongArch is a new RISC ISA, which is a bit like MIPS or RISC-V.
>> LoongArch includes a reduced 32-bit version (LA32R), a standard 32-bit
>> version (LA32S) and a 64-bit version (LA64). LoongArch use ACPI as its
>> boot protocol LoongArch-specific interrupt controllers (similar to APIC)
>> are already added in the ACPI Specification 6.5(which may be published in
>> early June this year and the board is reviewing the draft).
>>
>> Currently, LoongArch based processors (e.g. Loongson-3A5000) can only
>> work together with LS7A chipsets. The irq chips in LoongArch computers
>> include CPUINTC (CPU Core Interrupt Controller), LIOINTC (Legacy I/O
>> Interrupt Controller), EIOINTC (Extended I/O Interrupt Controller),
>> HTVECINTC (Hyper-Transport Vector Interrupt Controller), PCH-PIC (Main
>> Interrupt Controller in LS7A chipset), PCH-LPC (LPC Interrupt Controller
>> in LS7A chipset) and PCH-MSI (MSI Interrupt Controller).
>>
>> CPUINTC is a per-core controller (in CPU), LIOINTC/EIOINTC/HTVECINTC are
>> per-package controllers (in CPU), while PCH-PIC/PCH-LPC/PCH-MSI are all
>> controllers out of CPU (i.e., in chipsets). These controllers (in other
>> words, irqchips) are linked in a hierarchy, and there are two models of
>> hierarchy (legacy model and extended model).
>>
>> Legacy IRQ model:
>>
>> In this model, the IPI (Inter-Processor Interrupt) and CPU Local Timer
>> interrupt go to CPUINTC directly, CPU UARTS interrupts go to LIOINTC,
>> while all other devices interrupts go to PCH-PIC/PCH-LPC/PCH-MSI and
>> gathered by HTVECINTC, and then go to LIOINTC, and then CPUINTC.
>>
>>   +---------------------------------------------+
>>   |                                             |
>>   |    +-----+     +---------+     +-------+    |
>>   |    | IPI | --> | CPUINTC | <-- | Timer |    |
>>   |    +-----+     +---------+     +-------+    |
>>   |                     ^                       |
>>   |                     |                       |
>>   |                +---------+     +-------+    |
>>   |                | LIOINTC | <-- | UARTs |    |
>>   |                +---------+     +-------+    |
>>   |                     ^                       |
>>   |                     |                       |
>>   |               +-----------+                 |
>>   |               | HTVECINTC |                 |
>>   |               +-----------+                 |
>>   |                ^         ^                  |
>>   |                |         |                  |
>>   |          +---------+ +---------+            |
>>   |          | PCH-PIC | | PCH-MSI |            |
>>   |          +---------+ +---------+            |
>>   |            ^     ^           ^              |
>>   |            |     |           |              |
>>   |    +---------+ +---------+ +---------+      |
>>   |    | PCH-LPC | | Devices | | Devices |      |
>>   |    +---------+ +---------+ +---------+      |
>>   |         ^                                   |
>>   |         |                                   |
>>   |    +---------+                              |
>>   |    | Devices |                              |
>>   |    +---------+                              |
>>   |                                             |
>>   |                                             |
>>   +---------------------------------------------+
>>
>> Extended IRQ model:
>>
>> In this model, the IPI (Inter-Processor Interrupt) and CPU Local Timer
>> interrupt go to CPUINTC directly, CPU UARTS interrupts go to LIOINTC,
>> while all other devices interrupts go to PCH-PIC/PCH-LPC/PCH-MSI and
>> gathered by EIOINTC, and then go to to CPUINTC directly.
>>
>>   +--------------------------------------------------------+
>>   |                                                        |
>>   |         +-----+     +---------+     +-------+          |
>>   |         | IPI | --> | CPUINTC | <-- | Timer |          |
>>   |         +-----+     +---------+     +-------+          |
>>   |                      ^       ^                         |
>>   |                      |       |                         |
>>   |               +---------+ +---------+     +-------+    |
>>   |               | EIOINTC | | LIOINTC | <-- | UARTs |    |
>>   |               +---------+ +---------+     +-------+    |
>>   |                ^       ^                               |
>>   |                |       |                               |
>>   |         +---------+ +---------+                        |
>>   |         | PCH-PIC | | PCH-MSI |                        |
>>   |         +---------+ +---------+                        |
>>   |           ^     ^           ^                          |
>>   |           |     |           |                          |
>>   |   +---------+ +---------+ +---------+                  |
>>   |   | PCH-LPC | | Devices | | Devices |                  |
>>   |   +---------+ +---------+ +---------+                  |
>>   |        ^                                               |
>>   |        |                                               |
>>   |   +---------+                                          |
>>   |   | Devices |                                          |
>>   |   +---------+                                          |
>>   |                                                        |
>>   |                                                        |
>>   +--------------------------------------------------------+
>>
>> The hierarchy model is constructed by parsing irq contronler structures
>> in MADT. Some controllers((e.g. LIOINTC, HTVECINTC, EIOINTC and PCH-LPC)
>> are hardcodingly connected to their parents, so their irqdomins are
>> separately routed to their parents in a fixed way. Some controllers
>> (e.g. PCH-PIC and PCH-MSI) could be routed to different parents for 
>> different
>> CPU. The firmware will config EIOINTC for the newer CPU and config 
>> HTVECINTC
>> for old CPU in MADT. By this way, PCH-PIC and PCH-MSI irqdomain can 
>> only be
>> routed one parent irqdomin: HTVECINTC or EIOINTC.
>>
>> Cross-compile tool chain to build kernel:
>> https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20211202-cross-tools.tar.xz 
>>
>>
>> A CLFS-based Linux distro:
>> https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-system-2021-12-02.tar.bz2 
>>
>>
>> Loongson and LoongArch documentations:
>> https://github.com/loongson/LoongArch-Documentation
>>
>>
>> V1 -> V2:
>> 1, Remove queued patches;
>> 2, Move common logic of DT/ACPI probing to common functions;
>> 3, Split .suspend()/.resume() functions to separate patches.
>>
>> V2 -> V3:
>> 1, Fix a bug for loongson-pch-pic probe;
>> 2, Some minor improvements for LPC controller.
>>
>> V3 -> V4:
>> 1, Rework the CPU interrupt controller driver;
>> 2, Some minor improvements for other controllers.
>>
>> V4 -> V5:
>> 1, Add a description of LoonArch's IRQ model;
>> 2, Support multiple EIOINTCs in one system;
>> 3, Some minor improvements for other controllers.
>>
>> V5 -> V6:
>> 1, Attach a fwnode to CPUINTC irq domain;
>> 2, Use raw spinlock instead of generic spinlock;
>> 3, Improve the method of restoring EIOINTC state;
>> 4, Update documentation, comments and commit messages.
>>
>> V6 -> V7:
>> 1, Fix build warnings reported by kernel test robot.
>>
>> V7 -> V8:
>> 1, Add arguments sanity checking for irqchip init functions;
>> 2, Support Loongson-3C5000 (One NUMA Node includes 4 EIOINTC Node).
>>
>> V8 -> V9:
>> 1, Rebase on 5.17-rc5;
>> 2, Update cover letter;
>> 3, Some small improvements.
>>
>> V9 -> V10:
>> 1, Rebase on 5.17-rc6;
>> 2, Fix build warnings reported by kernel test robot.
>>
>> V10 -> V11:
>> 1, Rebase on 5.18-rc4;
>> 2, Fix irq affinity setting for EIOINTC;
>> 3, Fix hwirq allocation failure for EIOINTC.
>>
>> V11 -> RFC:
>> 1, Refactored the way to build irqchip hierarchy topology.
>>
> 
> Hi, Marc
> 
> The irqchip topology building is refactored as following way in this RFC 
> patches according to my reply in V10, please help to review them if they 
> are correct, thanks very much!
> 
> - Only call irqchip_init() in arch file.
> - Use IRQCHIP_ACPI_DECLARE to declare entry of CORE PIC.
> - Initialize irqdomains in fixed way from their parent irqdomain for 
> hardcodingly routing irqchips(liointc, htvec, eiointc and pch-lpc) in 
> hardware.
> - Initialize irqdomains in scaled way for scalable routing 
> irqchips(pch-pic and pch-msi).
> - For eiointc and htvec, they are exclusive, and only one kind of them 
> can be configured in MADT.
> 

For ARM, the pci msi irqdomain of a pci device is found(call 
iort_get_device_domain) by the mapping between pci segment and ITS id of 
PCI root complex node where the pci device is located(or behind) when 
setting the irqdomain for the device,so IORT provides the way to find 
the msi irqdomain for pci devices (and plat devices). For LoongArch(only 
has pci msi), we find the pci msi irqdomain of a pci device by the 
mapping between pci segment and the node id(the node id in bit44-47 of 
Base Address in MCFG and the node id of eiointc are same or translated 
in a fixed relation according to the CPU feature), so we don't use an 
extra table as IORT.

We first used a method similar to x86 to build irqchip topology in the 
patch V11, now, we changed the method use a way similar to ARM, please 
help to review it. And how should we change it if it's still not 
acceptable, thanks.

>> Huacai Chen (1):
>>    irqchip: Adjust Kconfig for Loongson
>>
>> Jianmin Lv (9):
>>    irqchip: Add LoongArch CPU interrupt controller support
>>    irqchip/loongson-pch-pic: Add ACPI init support
>>    irqchip/loongson-pch-pic: Add suspend/resume support
>>    irqchip/loongson-pch-msi: Add ACPI init support
>>    irqchip/loongson-htvec: Add ACPI init support
>>    irqchip/loongson-htvec: Add suspend/resume support
>>    irqchip/loongson-liointc: Add ACPI init support
>>    irqchip: Add Loongson Extended I/O interrupt controller  support
>>    irqchip: Add Loongson PCH LPC controller support
>>
>>   drivers/irqchip/Kconfig                    |  38 ++-
>>   drivers/irqchip/Makefile                   |   3 +
>>   drivers/irqchip/irq-loongarch-cpu.c        | 134 ++++++++++
>>   drivers/irqchip/irq-loongarch-pic-common.c |  66 +++++
>>   drivers/irqchip/irq-loongarch-pic-common.h |  22 ++
>>   drivers/irqchip/irq-loongson-eiointc.c     | 381 
>> +++++++++++++++++++++++++++++
>>   drivers/irqchip/irq-loongson-htvec.c       | 148 ++++++++---
>>   drivers/irqchip/irq-loongson-liointc.c     | 215 ++++++++++------
>>   drivers/irqchip/irq-loongson-pch-lpc.c     | 225 +++++++++++++++++
>>   drivers/irqchip/irq-loongson-pch-msi.c     | 138 +++++++----
>>   drivers/irqchip/irq-loongson-pch-pic.c     | 214 ++++++++++++++--
>>   include/linux/cpuhotplug.h                 |   1 +
>>   12 files changed, 1398 insertions(+), 187 deletions(-)
>>   create mode 100644 drivers/irqchip/irq-loongarch-cpu.c
>>   create mode 100644 drivers/irqchip/irq-loongarch-pic-common.c
>>   create mode 100644 drivers/irqchip/irq-loongarch-pic-common.h
>>   create mode 100644 drivers/irqchip/irq-loongson-eiointc.c
>>   create mode 100644 drivers/irqchip/irq-loongson-pch-lpc.c
>>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-05-18  1:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-15  3:37 [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
2022-05-15  3:37 ` [PATCH RFC 01/10] irqchip: Adjust Kconfig for Loongson Jianmin Lv
2022-05-15  3:37 ` [PATCH RFC 02/10] irqchip: Add LoongArch CPU interrupt controller support Jianmin Lv
2022-05-15  3:37 ` [PATCH RFC 03/10] irqchip/loongson-pch-pic: Add ACPI init support Jianmin Lv
2022-05-15  3:37 ` [PATCH RFC 04/10] irqchip/loongson-pch-pic: Add suspend/resume support Jianmin Lv
2022-05-15  3:37 ` [PATCH RFC 05/10] irqchip/loongson-pch-msi: Add ACPI init support Jianmin Lv
2022-05-15  3:37 ` [PATCH RFC 06/10] irqchip/loongson-htvec: " Jianmin Lv
2022-05-16 13:13 ` [PATCH RFC 00/10] irqchip: Add LoongArch-related irqchip drivers Jianmin Lv
2022-05-18  1:52   ` Jianmin Lv

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.