From 5d42bda1303593c1d58d7c3c3ff5da90807a1618 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 2 Jan 2026 23:52:43 +0800 Subject: [PATCH 1/9] BACKPORT: MIPS: Loongson64: dts: fix phy-related definition of LS7A GMAC Currently the LS7A GMAC device tree node lacks a proper phy-handle property pointing to the PHY node. In addition, the phy-mode property specifies "rgmii" without any internal delay information, which means the board trace needs to add 2ns delay to the RGMII data lines; but that isn't known to happen on any Loongson board. The ACPI-based initialization codepath, which is used on LoongArch-based 3A5000 + 7A1000 hardwares, specifies "rgmii-id" phy mode, which should be the one we are using. Add the lacking phy-handle property and set proper phy-mode. Tested on a LS3A4000_7A1000_NUC_BOARD_V2.1 board with YT8521S PHY. Signed-off-by: Icenowy Zheng Reviewed-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer --- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi index ee71045883e7e7..6dee85909f5a61 100644 --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi @@ -199,7 +199,8 @@ <13 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq", "eth_lpi"; interrupt-parent = <&pic>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; + phy-handle = <&phy0>; mdio { #address-cells = <1>; #size-cells = <0>; @@ -222,7 +223,8 @@ <15 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq", "eth_lpi"; interrupt-parent = <&pic>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; + phy-handle = <&phy1>; mdio { #address-cells = <1>; #size-cells = <0>; From b3aef31c363e292052d25dddf0ca2de6e7405782 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 31 Jan 2026 16:51:42 +0800 Subject: [PATCH 2/9] FROMLIST: genirq: reserve NR_IRQS_LEGACY IRQs in dynirq by default Several architectures define NR_IRQS_LEGACY to reserve a low range of IRQ numbers for fixed legacy allocations (e.g. ISA interrupts) which should not be handed out by the dynamic IRQ allocator. arch_dynirq_lower_bound() exists to enforce this, but today only x86 wires it up. In the current boot order this typically works because legacy IRQ domains register early and claim the low IRQ numbers first; however, that assumption breaks if the legacy controller is probed later. Make the default arch_dynirq_lower_bound() implementation honour NR_IRQS_LEGACY by clamping the allocation start to at least that value. Architectures that do not define NR_IRQS_LEGACY keep the current behaviour (effectively 0). Arm/PowerPC/MIPS/LoongArch use legacy IRQ domains for ISA interrupts and benefit from this change. x86 and s390 already provide their own implementations. Cc: linux-s390@vger.kernel.org Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Alexander Gordeev Co-developed-by: Jiaxun Yang Signed-off-by: Jiaxun Yang Signed-off-by: Icenowy Zheng --- kernel/softirq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/softirq.c b/kernel/softirq.c index 77198911b8dd4b..cdc77d52c36b29 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -1184,5 +1184,5 @@ int __init __weak arch_early_irq_init(void) unsigned int __weak arch_dynirq_lower_bound(unsigned int from) { - return from; + return MAX(from, NR_IRQS_LEGACY); } From 03968210483233e371909d5b4814b414c2d8ec06 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Jan 2026 01:59:33 +0800 Subject: [PATCH 3/9] FROMLIST: dt-bindings: interrupt-controller: add LS7A PCH LPC Loongson 7A series PCH contains an LPC controller with an interrupt controller. Add the device tree binding for the interrupt controller. Signed-off-by: Icenowy Zheng --- .../loongson,pch-lpc.yaml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/loongson,pch-lpc.yaml diff --git a/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-lpc.yaml b/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-lpc.yaml new file mode 100644 index 00000000000000..c00fbf31f47f05 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/loongson,pch-lpc.yaml @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interrupt-controller/loongson,pch-lpc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Loongson PCH LPC Controller + +maintainers: + - Jiaxun Yang + +description: + This interrupt controller is found in the Loongson LS7A family of PCH for + accepting interrupts sent by LPC-connected peripherals and signalling PIC + via a single interrupt line when interrupts are available. + +properties: + compatible: + const: loongson,pch-lpc-1.0 + + reg: + maxItems: 1 + + interrupt-controller: true + + interrupts: + maxItems: 1 + + '#interrupt-cells': + const: 2 + +required: + - compatible + - reg + - interrupt-controller + - interrupts + - '#interrupt-cells' + +additionalProperties: false + +examples: + - | + #include + lpc: interrupt-controller@10002000 { + compatible = "loongson,pch-lpc-1.0"; + reg = <0x10002000 0x400>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&pic>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; + }; +... From fe90dae5664b9ea2422980bbd84cd388d1928716 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Jan 2026 01:22:40 +0800 Subject: [PATCH 4/9] BACKPORT: FROMLIST: irqchip/loongson-pch-lpc: extract non-ACPI-related code from ACPI init A lot of code could be shared between the current ACPI init flow with the possible OF init flow. Extract them to a dedicated function. The re-ordering of parent IRQ acquisition requires the arch code to reserve legacy IRQs from dynirq allocation via overriding arch_dynirq_lower_bound(), otherwise the parent of LPC irqchip will be allocated to the intended static range of LPC IRQs, which leads to allocation failure of LPC IRQs. Co-developed-by: Jiaxun Yang Signed-off-by: Jiaxun Yang Signed-off-by: Icenowy Zheng --- drivers/irqchip/irq-loongson-pch-lpc.c | 56 +++++++++++++++++--------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/irqchip/irq-loongson-pch-lpc.c b/drivers/irqchip/irq-loongson-pch-lpc.c index 912bf50a5c7ca7..4463e6435e8ac5 100644 --- a/drivers/irqchip/irq-loongson-pch-lpc.c +++ b/drivers/irqchip/irq-loongson-pch-lpc.c @@ -171,13 +171,11 @@ static struct syscore_ops pch_lpc_syscore_ops = { .resume = pch_lpc_resume, }; -int __init pch_lpc_acpi_init(struct irq_domain *parent, - struct acpi_madt_lpc_pic *acpi_pchlpc) +static int __init pch_lpc_init(phys_addr_t addr, unsigned long size, + struct fwnode_handle *irq_handle, + int parent_irq) { - int parent_irq; struct pch_lpc *priv; - struct irq_fwspec fwspec; - struct fwnode_handle *irq_handle; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) @@ -185,7 +183,7 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, raw_spin_lock_init(&priv->lpc_lock); - priv->base = ioremap(acpi_pchlpc->address, acpi_pchlpc->size); + priv->base = ioremap(addr, size); if (!priv->base) goto free_priv; @@ -194,12 +192,6 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, goto iounmap_base; } - irq_handle = irq_domain_alloc_named_fwnode("lpcintc"); - if (!irq_handle) { - pr_err("Unable to allocate domain handle\n"); - goto iounmap_base; - } - /* * The LPC interrupt controller is a legacy i8259-compatible device, * which requires a static 1:1 mapping for IRQs 0-15. @@ -209,15 +201,10 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, &pch_lpc_domain_ops, priv); if (!priv->lpc_domain) { pr_err("Failed to create IRQ domain\n"); - goto free_irq_handle; + goto iounmap_base; } pch_lpc_reset(priv); - fwspec.fwnode = parent->fwnode; - fwspec.param[0] = acpi_pchlpc->cascade + GSI_MIN_PCH_IRQ; - fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH; - fwspec.param_count = 2; - parent_irq = irq_create_fwspec_mapping(&fwspec); irq_set_chained_handler_and_data(parent_irq, lpc_irq_dispatch, priv); pch_lpc_priv = priv; @@ -226,8 +213,6 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, return 0; -free_irq_handle: - irq_domain_free_fwnode(irq_handle); iounmap_base: iounmap(priv->base); free_priv: @@ -235,3 +220,34 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, return -ENOMEM; } + +int __init pch_lpc_acpi_init(struct irq_domain *parent, + struct acpi_madt_lpc_pic *acpi_pchlpc) +{ + int parent_irq; + struct pch_lpc *priv; + struct irq_fwspec fwspec; + struct fwnode_handle *irq_handle; + int ret; + + irq_handle = irq_domain_alloc_named_fwnode("lpcintc"); + if (!irq_handle) { + pr_err("Unable to allocate domain handle\n"); + return -ENOMEM; + } + + fwspec.fwnode = parent->fwnode; + fwspec.param[0] = acpi_pchlpc->cascade + GSI_MIN_PCH_IRQ; + fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH; + fwspec.param_count = 2; + parent_irq = irq_create_fwspec_mapping(&fwspec); + + ret = pch_lpc_init(acpi_pchlpc->address, acpi_pchlpc->size, + irq_handle, parent_irq); + if (ret) { + irq_domain_free_fwnode(irq_handle); + return ret; + } + + return 0; +} From 5755c78697290d5840966bb55f540c2d33141f87 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Jan 2026 01:27:26 +0800 Subject: [PATCH 5/9] FROMLIST: irqchip/loongson-pch-lpc: guard ACPI init code with CONFIG_ACPI As OF-based initialization is going to be added to the driver, guard the ACPI-based initialization code with CONFIG_ACPI. Co-developed-by: Jiaxun Yang Signed-off-by: Jiaxun Yang Signed-off-by: Icenowy Zheng --- drivers/irqchip/irq-loongson-pch-lpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/irqchip/irq-loongson-pch-lpc.c b/drivers/irqchip/irq-loongson-pch-lpc.c index 4463e6435e8ac5..11f1df2bafaf4d 100644 --- a/drivers/irqchip/irq-loongson-pch-lpc.c +++ b/drivers/irqchip/irq-loongson-pch-lpc.c @@ -221,6 +221,7 @@ static int __init pch_lpc_init(phys_addr_t addr, unsigned long size, return -ENOMEM; } +#ifdef CONFIG_ACPI int __init pch_lpc_acpi_init(struct irq_domain *parent, struct acpi_madt_lpc_pic *acpi_pchlpc) { @@ -251,3 +252,4 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, return 0; } +#endif /* CONFIG_ACPI */ From ec64439c894f3b15158e8ad833e98e7d1e0166e6 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Jan 2026 01:41:50 +0800 Subject: [PATCH 6/9] FROMLIST: irqchip/loongson-pch-lpc: add OF init code As the (kernel-internally) OF-based MIPS Loongson-3 systems can also have PCH LPC interrupt controller, add OF-based initialization code for the driver. Co-developed-by: Jiaxun Yang Signed-off-by: Jiaxun Yang Signed-off-by: Icenowy Zheng --- drivers/irqchip/irq-loongson-pch-lpc.c | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/irqchip/irq-loongson-pch-lpc.c b/drivers/irqchip/irq-loongson-pch-lpc.c index 11f1df2bafaf4d..cea34de994cef7 100644 --- a/drivers/irqchip/irq-loongson-pch-lpc.c +++ b/drivers/irqchip/irq-loongson-pch-lpc.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include "irq-loongson.h" @@ -253,3 +255,29 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, return 0; } #endif /* CONFIG_ACPI */ + +#ifdef CONFIG_OF +static int pch_lpc_of_init(struct device_node *node, + struct device_node *parent) +{ + int parent_irq; + struct fwnode_handle *irq_handle; + struct resource res; + + if (of_address_to_resource(node, 0, &res)) + return -EINVAL; + + parent_irq = irq_of_parse_and_map(node, 0); + if (!parent_irq) { + pr_err("Failed to get the parent IRQ for LPC IRQs\n"); + return -EINVAL; + } + + irq_handle = of_fwnode_handle(node); + + return pch_lpc_init(res.start, resource_size(&res), irq_handle, + parent_irq); +} + +IRQCHIP_DECLARE(pch_lpc, "loongson,pch-lpc-1.0", pch_lpc_of_init); +#endif /* CONFIG_OF */ From 856efc2642a43016644cd3895446a43ad8404616 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Jan 2026 01:45:01 +0800 Subject: [PATCH 7/9] FROMLIST: irqchip/loongson-pch-lpc: enable building on MIPS Loongson64 As the driver can now support OF-based platforms, it's now possible to use it on MIPS Loongson64 machines. Drop the requirement of LOONGARCH for this driver, to allow build on both MIPS-based and LoongArch-based Loongson systems. Signed-off-by: Icenowy Zheng --- drivers/irqchip/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index a61c6dc63c29cf..b478b3089d7787 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -758,7 +758,6 @@ config LOONGSON_PCH_MSI config LOONGSON_PCH_LPC bool "Loongson PCH LPC Controller" - depends on LOONGARCH depends on MACH_LOONGSON64 default MACH_LOONGSON64 select IRQ_DOMAIN_HIERARCHY From bba600b080102fefc6c67180c026a50389bdd434 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 15 Jan 2026 12:03:45 +0800 Subject: [PATCH 8/9] FROMLIST: MIPS: Loongson64: dts: sort nodes The RTC's address is after UARTs, however the node is currently before them. Re-order the node to match address sequence. Signed-off-by: Icenowy Zheng --- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi index 6dee85909f5a61..59ca1ef0a7b64e 100644 --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi @@ -19,13 +19,6 @@ #interrupt-cells = <2>; }; - rtc0: rtc@100d0100 { - compatible = "loongson,ls7a-rtc"; - reg = <0 0x100d0100 0 0x78>; - interrupt-parent = <&pic>; - interrupts = <52 IRQ_TYPE_LEVEL_HIGH>; - }; - ls7a_uart0: serial@10080000 { compatible = "ns16550a"; reg = <0 0x10080000 0 0x100>; @@ -65,6 +58,13 @@ no-loopback-test; }; + rtc0: rtc@100d0100 { + compatible = "loongson,ls7a-rtc"; + reg = <0 0x100d0100 0 0x78>; + interrupt-parent = <&pic>; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH>; + }; + pci@1a000000 { compatible = "loongson,ls7a-pci"; device_type = "pci"; From 4879bf8f67d13dec7e7c094a37a7b954f2863df7 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 16 Jan 2026 01:48:34 +0800 Subject: [PATCH 9/9] FROMLIST: MIPS: Loongson64: dts: add node for LS7A PCH LPC Loongson 7A series PCH contain a LPC IRQ controller. Add the device tree node of it. Signed-off-by: Icenowy Zheng --- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi index 59ca1ef0a7b64e..d41ca0b3d6511b 100644 --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi @@ -19,6 +19,15 @@ #interrupt-cells = <2>; }; + lpc: interrupt-controller@10002000 { + compatible = "loongson,pch-lpc-1.0"; + reg = <0 0x10002000 0 0x1000>; + interrupt-controller; + interrupt-parent = <&pic>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <2>; + }; + ls7a_uart0: serial@10080000 { compatible = "ns16550a"; reg = <0 0x10080000 0 0x100>;