[PATCH 2/4] irqchip/ast2700-intcx: Add AST2700 INTC0/INTC1 support

Ryan Chen posted 4 patches 3 days, 11 hours ago
[PATCH 2/4] irqchip/ast2700-intcx: Add AST2700 INTC0/INTC1 support
Posted by Ryan Chen 3 days, 11 hours ago
The AST2700 interrupt fabric is shared by multiple integrated processors
(PSP/SSP/TSP/BootMCU), each with its own interrupt controller and its own
devicetree view of the system. As a result, interrupt routing cannot be
treated as fixed: the valid route for a peripheral interrupt depends on
which processor is consuming it.

The INTC0 driver models this by creating a hierarchical irqdomain under
the upstream interrupt controller selected by the interrupt-parent
property in the devicetree. Information derived from this relationship
is incorporated into the route resolution logic for the controller.

The INTC1 driver implements the banked INTM-fed controller and forwards
interrupts toward INTC0, without embedding assumptions about the final
destination processor.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
 drivers/irqchip/Kconfig                  |  11 +
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-ast2700-intc0-test.c | 474 +++++++++++++++++++
 drivers/irqchip/irq-ast2700-intc0.c      | 770 +++++++++++++++++++++++++++++++
 drivers/irqchip/irq-ast2700-intc1.c      | 345 ++++++++++++++
 drivers/irqchip/irq-ast2700.c            | 105 +++++
 drivers/irqchip/irq-ast2700.h            |  37 ++
 7 files changed, 1743 insertions(+)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f334f49c9791..3cc0f3af0e1e 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -110,6 +110,17 @@ config AL_FIC
 	help
 	  Support Amazon's Annapurna Labs Fabric Interrupt Controller.
 
+config ASPEED_AST2700_INTC
+	bool "ASPEED AST2700 Interrupt Controller support"
+	depends on OF
+	depends on ARCH_ASPEED || COMPILE_TEST
+	select IRQ_DOMAIN_HIERARCHY
+
+config ASPEED_AST2700_INTC_TEST
+	bool "Tests for the ASPEED AST2700 Interrupt Controller"
+	depends on ASPEED_AST2700_INTC && KUNIT=y
+	default KUNIT_ALL_TESTS
+
 config ATMEL_AIC_IRQ
 	bool
 	select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 6a229443efe0..51fdf269e436 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_MVEBU_PIC)			+= irq-mvebu-pic.o
 obj-$(CONFIG_MVEBU_SEI)			+= irq-mvebu-sei.o
 obj-$(CONFIG_LS_EXTIRQ)			+= irq-ls-extirq.o
 obj-$(CONFIG_LS_SCFG_MSI)		+= irq-ls-scfg-msi.o
+obj-$(CONFIG_ASPEED_AST2700_INTC)	+= irq-ast2700.o irq-ast2700-intc0.o irq-ast2700-intc1.o
 obj-$(CONFIG_ARCH_ASPEED)		+= irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o
 obj-$(CONFIG_ARCH_ASPEED)		+= irq-aspeed-intc.o
 obj-$(CONFIG_STM32MP_EXTI)		+= irq-stm32mp-exti.o
diff --git a/drivers/irqchip/irq-ast2700-intc0-test.c b/drivers/irqchip/irq-ast2700-intc0-test.c
new file mode 100644
index 000000000000..d6bc19676b2e
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700-intc0-test.c
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Copyright (C) 2026 Code Construct
+ */
+#include <kunit/test.h>
+#include "irq-ast2700.h"
+
+static void aspeed_intc0_resolve_route_bad_args(struct kunit *test)
+{
+	static const struct aspeed_intc_interrupt_range c1ranges[] = { 0 };
+	static const aspeed_intc_output_t c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	const struct irq_domain c0domain = { 0 };
+
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(NULL, 0, c1outs, 0, c1ranges, NULL);
+	KUNIT_EXPECT_EQ(test, rc, -EINVAL);
+
+	rc = aspeed_intc0_resolve_route(&c0domain, 0, c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_EQ(test, rc, -ENODEV);
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					0, c1ranges, &resolved);
+	KUNIT_EXPECT_EQ(test, rc, -ENODEV);
+}
+
+static int
+arm_gicv3_fwnode_read_string_array(const struct fwnode_handle *fwnode_handle,
+				   const char *propname, const char **val,
+				   size_t nval)
+{
+	if (!propname)
+		return -EINVAL;
+
+	if (!val)
+		return 1;
+
+	if (WARN_ON(nval != 1))
+		return -EOVERFLOW;
+
+	*val = "arm,gic-v3";
+	return 1;
+}
+
+static const struct fwnode_operations arm_gicv3_fwnode_ops = {
+	.property_read_string_array = arm_gicv3_fwnode_read_string_array,
+};
+
+static void aspeed_intc_resolve_route_invalid_c0domain(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &arm_gicv3_fwnode_ops },
+	};
+	const struct irq_domain c0domain = { .fwnode = &intc0_node.fwnode };
+	static const struct aspeed_intc_interrupt_range c1ranges[] = { 0 };
+	static const aspeed_intc_output_t c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_NE(test, rc, 0);
+}
+
+static int
+aspeed_intc0_fwnode_read_string_array(const struct fwnode_handle *fwnode_handle,
+				      const char *propname, const char **val,
+				      size_t nval)
+{
+	if (!propname)
+		return -EINVAL;
+
+	if (!val)
+		return 1;
+
+	if (WARN_ON(nval != 1))
+		return -EOVERFLOW;
+
+	*val = "aspeed,ast2700-intc0-ic";
+	return nval;
+}
+
+static const struct fwnode_operations intc0_fwnode_ops = {
+	.property_read_string_array = aspeed_intc0_fwnode_read_string_array,
+};
+
+static void
+aspeed_intc0_resolve_route_c1i1o1c0i1o1_connected(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &intc0_fwnode_ops },
+	};
+	struct aspeed_intc_interrupt_range c1ranges[] = {
+		{
+			.start = 0,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 1,
+				.param = { 128 }
+			}
+		}
+	};
+	static const aspeed_intc_output_t c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	struct aspeed_intc_interrupt_range intc0_ranges[] = {
+		{
+			.start = 128,
+			.count = 1,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = { 0 },
+			}
+		}
+	};
+	struct aspeed_intc0 intc0 = {
+		.ranges = { .ranges = intc0_ranges, .nranges = ARRAY_SIZE(intc0_ranges), }
+	};
+	const struct irq_domain c0domain = {
+		.host_data = &intc0,
+		.fwnode = &intc0_node.fwnode
+	};
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_EQ(test, rc, 0);
+	KUNIT_EXPECT_EQ(test, resolved.start, 0);
+	KUNIT_EXPECT_EQ(test, resolved.count, 1);
+	KUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 128);
+}
+
+static void
+aspeed_intc0_resolve_route_c1i1o1c0i1o1_disconnected(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &intc0_fwnode_ops },
+	};
+	struct aspeed_intc_interrupt_range c1ranges[] = {
+		{
+			.start = 0,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 1,
+				.param = { 128 }
+			}
+		}
+	};
+	static const aspeed_intc_output_t c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	struct aspeed_intc_interrupt_range intc0_ranges[] = {
+		{
+			.start = 129,
+			.count = 1,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = { 0 },
+			}
+		}
+	};
+	struct aspeed_intc0 intc0 = {
+		.ranges = {
+			.ranges = intc0_ranges,
+			.nranges = ARRAY_SIZE(intc0_ranges),
+		}
+	};
+	const struct irq_domain c0domain = {
+		.host_data = &intc0,
+		.fwnode = &intc0_node.fwnode
+	};
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_NE(test, rc, 0);
+}
+
+static void aspeed_intc0_resolve_route_c1i1o1mc0i1o1(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &intc0_fwnode_ops },
+	};
+	struct aspeed_intc_interrupt_range c1ranges[] = {
+		{
+			.start = 0,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 1,
+				.param = { 480 }
+			}
+		}
+	};
+	static const aspeed_intc_output_t c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	struct aspeed_intc_interrupt_range intc0_ranges[] = {
+		{
+			.start = 192,
+			.count = 1,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = { 0 },
+			}
+		}
+	};
+	struct aspeed_intc0 intc0 = {
+		.ranges = {
+			.ranges = intc0_ranges,
+			.nranges = ARRAY_SIZE(intc0_ranges),
+		}
+	};
+	const struct irq_domain c0domain = {
+		.host_data = &intc0,
+		.fwnode = &intc0_node.fwnode
+	};
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_EQ(test, rc, 0);
+	KUNIT_EXPECT_EQ(test, resolved.start, 0);
+	KUNIT_EXPECT_EQ(test, resolved.count, 1);
+	KUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 480);
+}
+
+static void aspeed_intc0_resolve_route_c1i2o2mc0i1o1(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &intc0_fwnode_ops },
+	};
+	struct aspeed_intc_interrupt_range c1ranges[] = {
+		{
+			.start = 0,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 1,
+				.param = { 480 }
+			}
+		},
+		{
+			.start = 1,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 1,
+				.param = { 510 }
+			}
+		}
+	};
+	static const aspeed_intc_output_t c1outs[] = { 1 };
+	struct aspeed_intc_interrupt_range resolved;
+	struct aspeed_intc_interrupt_range intc0_ranges[] = {
+		{
+			.start = 208,
+			.count = 1,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = { 0 },
+			}
+		}
+	};
+	struct aspeed_intc0 intc0 = {
+		.ranges = {
+			.ranges = intc0_ranges,
+			.nranges = ARRAY_SIZE(intc0_ranges),
+		}
+	};
+	const struct irq_domain c0domain = {
+		.host_data = &intc0,
+		.fwnode = &intc0_node.fwnode
+	};
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_EQ(test, rc, 0);
+	KUNIT_EXPECT_EQ(test, resolved.start, 1);
+	KUNIT_EXPECT_EQ(test, resolved.count, 1);
+	KUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 510);
+}
+
+static void aspeed_intc0_resolve_route_c1i1o1mc0i2o1(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &intc0_fwnode_ops },
+	};
+	struct aspeed_intc_interrupt_range c1ranges[] = {
+		{
+			.start = 0,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 1,
+				.param = { 510 }
+			}
+		},
+	};
+	static const aspeed_intc_output_t c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	struct aspeed_intc_interrupt_range intc0_ranges[] = {
+		{
+			.start = 192,
+			.count = 1,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = {0},
+			}
+		},
+		{
+			.start = 208,
+			.count = 1,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = {0},
+			}
+		}
+	};
+	struct aspeed_intc0 intc0 = {
+		.ranges = {
+			.ranges = intc0_ranges,
+			.nranges = ARRAY_SIZE(intc0_ranges),
+		}
+	};
+	const struct irq_domain c0domain = {
+		.host_data = &intc0,
+		.fwnode = &intc0_node.fwnode
+	};
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_EQ(test, rc, 0);
+	KUNIT_EXPECT_EQ(test, resolved.start, 0);
+	KUNIT_EXPECT_EQ(test, resolved.count, 1);
+	KUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 510);
+}
+
+static void aspeed_intc0_resolve_route_c1i1o2mc0i1o1_invalid(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &intc0_fwnode_ops },
+	};
+	struct aspeed_intc_interrupt_range c1ranges[] = {
+		{
+			.start = 0,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 1,
+				.param = { 480 }
+			}
+		}
+	};
+	static const aspeed_intc_output_t c1outs[] = {
+		AST2700_INTC_INVALID_ROUTE, 0
+	};
+	struct aspeed_intc_interrupt_range resolved;
+	struct aspeed_intc_interrupt_range intc0_ranges[] = {
+		{
+			.start = 192,
+			.count = 1,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = { 0 },
+			}
+		}
+	};
+	struct aspeed_intc0 intc0 = {
+		.ranges = {
+			.ranges = intc0_ranges,
+			.nranges = ARRAY_SIZE(intc0_ranges),
+		}
+	};
+	const struct irq_domain c0domain = {
+		.host_data = &intc0,
+		.fwnode = &intc0_node.fwnode
+	};
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_EQ(test, rc, 1);
+	KUNIT_EXPECT_EQ(test, resolved.start, 0);
+	KUNIT_EXPECT_EQ(test, resolved.count, 1);
+	KUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 480);
+}
+
+static void
+aspeed_intc0_resolve_route_c1i1o1mc0i1o1_bad_range_upstream(struct kunit *test)
+{
+	struct device_node intc0_node = {
+		.fwnode = { .ops = &intc0_fwnode_ops },
+	};
+	struct aspeed_intc_interrupt_range c1ranges[] = {
+		{
+			.start = 0,
+			.count = 1,
+			.upstream = {
+				.fwnode = &intc0_node.fwnode,
+				.param_count = 0,
+				.param = { 0 }
+			}
+		}
+	};
+	static const aspeed_intc_output_t c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	struct aspeed_intc_interrupt_range intc0_ranges[] = {
+		{
+			.start = 0,
+			.count = 0,
+			.upstream = {
+				.fwnode = NULL,
+				.param_count = 0,
+				.param = { 0 },
+			}
+		}
+	};
+	struct aspeed_intc0 intc0 = {
+		.ranges = {
+			.ranges = intc0_ranges,
+			.nranges = ARRAY_SIZE(intc0_ranges),
+		}
+	};
+	const struct irq_domain c0domain = {
+		.host_data = &intc0,
+		.fwnode = &intc0_node.fwnode
+	};
+	int rc;
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					ARRAY_SIZE(c1ranges), c1ranges,
+					&resolved);
+	KUNIT_EXPECT_NE(test, rc, 0);
+}
+
+static struct kunit_case ast2700_intc0_test_cases[] = {
+	KUNIT_CASE(aspeed_intc0_resolve_route_bad_args),
+	KUNIT_CASE(aspeed_intc_resolve_route_invalid_c0domain),
+	KUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1c0i1o1_connected),
+	KUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1c0i1o1_disconnected),
+	KUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1mc0i1o1),
+	KUNIT_CASE(aspeed_intc0_resolve_route_c1i2o2mc0i1o1),
+	KUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1mc0i2o1),
+	KUNIT_CASE(aspeed_intc0_resolve_route_c1i1o2mc0i1o1_invalid),
+	KUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1mc0i1o1_bad_range_upstream),
+	{},
+};
+
+static struct kunit_suite ast2700_intc0_test_suite = {
+	.name = "ast2700-intc0",
+	.test_cases = ast2700_intc0_test_cases,
+};
+kunit_test_suite(ast2700_intc0_test_suite);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/irqchip/irq-ast2700-intc0.c b/drivers/irqchip/irq-ast2700-intc0.c
new file mode 100644
index 000000000000..722457dd2e18
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700-intc0.c
@@ -0,0 +1,770 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Aspeed Interrupt Controller.
+ *
+ *  Copyright (C) 2023 ASPEED Technology Inc.
+ */
+
+#include <asm-generic/errno.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/fwnode.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kconfig.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/property.h>
+#include <linux/spinlock.h>
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "irq-ast2700.h"
+#define INT_NUM 480
+#define INTM_NUM 50
+#define SWINT_NUM 16
+
+#define INTM_BASE (INT_NUM)
+#define SWINT_BASE (INT_NUM + INTM_NUM)
+#define INT0_NUM (INT_NUM + INTM_NUM + SWINT_NUM)
+
+#define GIC_P2P_SPI_END 128
+
+#define INTC0_SWINT_IER 0x10
+#define INTC0_SWINT_ISR 0x14
+#define INTC0_INTBANKX_IER 0x1000
+#define INTC0_INTBANK_GROUPS 11
+#define INTC0_INTBANKS_PER_GRP 3
+#define INTC0_INTMX_IER 0x1b00
+#define INTC0_INTMX_ISR 0x1b04
+#define INTC0_INTM_BANK_NUM 3
+#define INTM_IRQS_PER_BANK 10
+
+struct aspeed_intc0 {
+	struct device *dev;
+	void __iomem *base;
+	raw_spinlock_t intc_lock;
+	struct irq_domain *local;
+	struct device_node *parent;
+	struct aspeed_intc_interrupt_ranges ranges;
+};
+
+static void aspeed_swint_irq_mask(struct irq_data *data)
+{
+	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
+	int bit = data->hwirq - SWINT_BASE;
+	unsigned int mask;
+
+	guard(raw_spinlock_irqsave)(&intc0->intc_lock);
+	mask = readl(intc0->base + INTC0_SWINT_IER) & ~BIT(bit);
+	writel(mask, intc0->base + INTC0_SWINT_IER);
+	irq_chip_mask_parent(data);
+}
+
+static void aspeed_swint_irq_unmask(struct irq_data *data)
+{
+	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
+	int bit = data->hwirq - SWINT_BASE;
+	unsigned int unmask;
+
+	guard(raw_spinlock_irqsave)(&intc0->intc_lock);
+	unmask = readl(intc0->base + INTC0_SWINT_IER) | BIT(bit);
+	writel(unmask, intc0->base + INTC0_SWINT_IER);
+	irq_chip_unmask_parent(data);
+}
+
+static void aspeed_swint_irq_eoi(struct irq_data *data)
+{
+	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
+	int bit = data->hwirq - SWINT_BASE;
+
+	writel(BIT(bit), intc0->base + INTC0_SWINT_ISR);
+	irq_chip_eoi_parent(data);
+}
+
+static struct irq_chip aspeed_swint_chip = {
+	.name = "ast2700-swint",
+	.irq_eoi = aspeed_swint_irq_eoi,
+	.irq_mask = aspeed_swint_irq_mask,
+	.irq_unmask = aspeed_swint_irq_unmask,
+	.irq_set_affinity = irq_chip_set_affinity_parent,
+	.flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static void aspeed_intc0_irq_mask(struct irq_data *data)
+{
+	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
+	int bank = (data->hwirq - INTM_BASE) / INTM_IRQS_PER_BANK;
+	int bit = (data->hwirq - INTM_BASE) % INTM_IRQS_PER_BANK;
+	unsigned int mask;
+
+	guard(raw_spinlock_irqsave)(&intc0->intc_lock);
+	mask = readl(intc0->base + INTC0_INTMX_IER + bank * 0x10) & ~BIT(bit);
+	writel(mask, intc0->base + INTC0_INTMX_IER + bank * 0x10);
+	irq_chip_mask_parent(data);
+}
+
+static void aspeed_intc0_irq_unmask(struct irq_data *data)
+{
+	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
+	int bank = (data->hwirq - INTM_BASE) / INTM_IRQS_PER_BANK;
+	int bit = (data->hwirq - INTM_BASE) % INTM_IRQS_PER_BANK;
+	unsigned int unmask;
+
+	guard(raw_spinlock_irqsave)(&intc0->intc_lock);
+	unmask = readl(intc0->base + INTC0_INTMX_IER + bank * 0x10) | BIT(bit);
+	writel(unmask, intc0->base + INTC0_INTMX_IER + bank * 0x10);
+	irq_chip_unmask_parent(data);
+}
+
+static void aspeed_intc0_irq_eoi(struct irq_data *data)
+{
+	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
+	int bank = (data->hwirq - INTM_BASE) / INTM_IRQS_PER_BANK;
+	int bit = (data->hwirq - INTM_BASE) % INTM_IRQS_PER_BANK;
+
+	writel(BIT(bit), intc0->base + INTC0_INTMX_ISR + bank * 0x10);
+	irq_chip_eoi_parent(data);
+}
+
+static struct irq_chip aspeed_intm_chip = {
+	.name = "ast2700-intmerge",
+	.irq_eoi = aspeed_intc0_irq_eoi,
+	.irq_mask = aspeed_intc0_irq_mask,
+	.irq_unmask = aspeed_intc0_irq_unmask,
+	.irq_set_affinity = irq_chip_set_affinity_parent,
+	.flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static struct irq_chip linear_intr_irq_chip = {
+	.name = "ast2700-int",
+	.irq_eoi = irq_chip_eoi_parent,
+	.irq_mask = irq_chip_mask_parent,
+	.irq_unmask = irq_chip_unmask_parent,
+	.irq_set_affinity = irq_chip_set_affinity_parent,
+	.flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+#define INTC0_IN_NUM 480
+#define INTC0_ROUTE_NUM 5
+
+static const aspeed_intc_output_t aspeed_intc0_routes[INTC0_IN_NUM / 32][INTC0_ROUTE_NUM] = {
+	[0] = {
+		[0b000] = 0,
+		[0b001] = 256,
+		[0b010] = 426,
+		[0b011] = AST2700_INTC_INVALID_ROUTE,
+		[0b100] = AST2700_INTC_INVALID_ROUTE,
+	},
+	[1] = {
+		[0b000] = 32,
+		[0b001] = 288,
+		[0b010] = 458,
+		[0b011] = AST2700_INTC_INVALID_ROUTE,
+		[0b100] = AST2700_INTC_INVALID_ROUTE,
+	},
+	[2] = {
+		[0b000] = 64,
+		[0b001] = 320,
+		[0b010] = 490,
+		[0b011] = AST2700_INTC_INVALID_ROUTE,
+		[0b100] = AST2700_INTC_INVALID_ROUTE,
+	},
+	[3] = {
+		[0b000] = 96,
+		[0b001] = 352,
+		[0b010] = 522,
+		[0b011] = AST2700_INTC_INVALID_ROUTE,
+		[0b100] = AST2700_INTC_INVALID_ROUTE,
+	},
+	[4] = {
+		[0b000] = 128,
+		[0b001] = 384,
+		[0b010] = 554,
+		[0b011] = 160,
+		[0b100] = 176,
+	},
+	[5] = {
+		[0b000] = 129,
+		[0b001] = 385,
+		[0b010] = 555,
+		[0b011] = 161,
+		[0b100] = 177,
+	},
+	[6] = {
+		[0b000] = 130,
+		[0b001] = 386,
+		[0b010] = 556,
+		[0b011] = 162,
+		[0b100] = 178,
+	},
+	[7] = {
+		[0b000] = 131,
+		[0b001] = 387,
+		[0b010] = 557,
+		[0b011] = 163,
+		[0b100] = 179,
+	},
+	[8] = {
+		[0b000] = 132,
+		[0b001] = 388,
+		[0b010] = 558,
+		[0b011] = 164,
+		[0b100] = 180,
+
+	},
+	[9] = {
+		[0b000] = 133,
+		[0b001] = 544,
+		[0b010] = 714,
+		[0b011] = 165,
+		[0b100] = 181,
+	},
+	[10] = {
+		[0b000] = 134,
+		[0b001] = 545,
+		[0b010] = 715,
+		[0b011] = 166,
+		[0b100] = 182,
+	},
+	[11] = {
+		[0b000] = 135,
+		[0b001] = 546,
+		[0b010] = 706,
+		[0b011] = 167,
+		[0b100] = 183,
+	},
+	[12] = {
+		[0b000] = 136,
+		[0b001] = 547,
+		[0b010] = 707,
+		[0b011] = 168,
+		[0b100] = 184,
+
+	},
+	[13] = {
+		[0b000] = 137,
+		[0b001] = 548,
+		[0b010] = 708,
+		[0b011] = 169,
+		[0b100] = 185,
+
+	},
+	[14] = {
+		[0b000] = 138,
+		[0b001] = 549,
+		[0b010] = 709,
+		[0b011] = 170,
+		[0b100] = 186,
+	},
+};
+
+#define INTC0_INTM_NUM 50
+
+static const aspeed_intc_output_t
+	aspeed_intc0_intm_routes[INTC0_INTM_NUM / 10] = {
+		[0] = 192, /* INTM00 ~ INTM09 */
+		[1] = 416, /* INTM10 ~ INTM19 */
+		[2] = 586, /* INTM20 ~ INTM29 */
+		[3] = 208, /* INTM30 ~ INTM39 */
+		[4] = 224, /* INTM40 ~ INTM49 */
+	};
+
+static bool range_contains_element(u32 start, u32 count, u32 value)
+{
+	if (WARN_ON_ONCE((U32_MAX - count) < start))
+		return false;
+
+	return value >= start && value < start + count;
+}
+
+static int
+resolve_input_from_child_ranges(const struct aspeed_intc0 *intc0,
+				const struct aspeed_intc_interrupt_range *range,
+				u32 outpin, u32 *input)
+{
+	u32 offset;
+	u32 base;
+
+	if (!range_contains_element(range->start, range->count, outpin))
+		return -ENOENT;
+
+	if (range->upstream.param_count == 0)
+		return -EINVAL;
+
+	base = range->upstream.param[0];
+	offset = outpin - range->start;
+	if ((U32_MAX - offset) < base) {
+		dev_warn(intc0->dev,
+			 "%s: Arithmetic overflow for input derivation: %u + %u\n",
+			 __func__, base, offset);
+		return -EINVAL;
+	}
+
+	*input = base + offset;
+	return 0;
+}
+
+static bool resolve_parent_range_for_output(const struct aspeed_intc0 *intc0,
+					    const struct fwnode_handle *parent,
+					    u32 output,
+					    struct aspeed_intc_interrupt_range *resolved)
+{
+	for (size_t i = 0; i < intc0->ranges.nranges; i++) {
+		struct aspeed_intc_interrupt_range range =
+			intc0->ranges.ranges[i];
+
+		dev_dbg(intc0->dev,
+			"%s: Inspecting candidate parent range %zu starting at %u for %u\n",
+			__func__, i, range.start, range.count);
+		if (!range_contains_element(range.start, range.count, output)) {
+			dev_dbg(intc0->dev, "%s: Output %u not in range [%u, %u)\n",
+				__func__, output, range.start, range.start + range.count);
+			continue;
+		}
+
+		if (range.upstream.fwnode != parent) {
+			dev_dbg(intc0->dev, "%s: Parent mismatch for range %zu\n", __func__, i);
+			continue;
+		}
+
+		dev_dbg(intc0->dev, "%s: Parent range %zu matched for output %u\n",
+			__func__, i, output);
+
+		if (resolved) {
+			resolved->start = output;
+			resolved->count = 1;
+			resolved->upstream = range.upstream;
+			resolved->upstream.param[1] += output - range.start;
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
+static int resolve_parent_route_for_input(const struct aspeed_intc0 *intc0,
+					  const struct fwnode_handle *parent, u32 input,
+					  struct aspeed_intc_interrupt_range *resolved)
+{
+	aspeed_intc_output_t c0o;
+	int rc = -ENOENT;
+
+	if (input < INT_NUM) {
+		bool found;
+
+		dev_dbg(intc0->dev, "%s: Resolving parent route for linear input %u\n",
+			__func__, input);
+		static_assert(INTC0_ROUTE_NUM < INT_MAX, "Broken cast");
+		for (size_t i = 0; rc == -ENOENT && i < INTC0_ROUTE_NUM; i++) {
+			c0o = aspeed_intc0_routes[input / 32][i];
+			if (c0o == AST2700_INTC_INVALID_ROUTE)
+				continue;
+
+			if (input < GIC_P2P_SPI_END)
+				c0o += input % 32;
+
+			found = resolve_parent_range_for_output(intc0, parent, c0o, resolved);
+			rc = found ? (int)i : -ENOENT;
+		}
+	} else if (input < (INT_NUM + INTM_NUM)) {
+		bool found;
+
+		dev_dbg(intc0->dev, "%s: Resolving parent route for merged input %u\n",
+			__func__, input);
+		c0o = aspeed_intc0_intm_routes[(input - INT_NUM) / INTM_IRQS_PER_BANK];
+		c0o += ((input - INT_NUM) % INTM_IRQS_PER_BANK);
+
+		found = resolve_parent_range_for_output(intc0, parent, c0o, resolved);
+		rc = found ? 0 : -ENOENT;
+	} else if (input < (INT_NUM + INTM_NUM + SWINT_NUM)) {
+		bool found;
+
+		dev_dbg(intc0->dev, "%s: Resolving parent route for merged input %u\n",
+			__func__, input);
+		c0o = input - SWINT_BASE + 144;
+		found = resolve_parent_range_for_output(intc0, parent, c0o, resolved);
+		rc = found ? 0 : -ENOENT;
+	} else {
+		dev_dbg(intc0->dev, "%s: Invalid input: %u\n", __func__, input);
+		return -ENOENT;
+	}
+
+	if (rc < 0) {
+		dev_dbg(intc0->dev,
+			"%s: Failed to resolve INTC0 parent route for input %u: %d\n",
+			__func__, input, rc);
+	} else {
+		dev_dbg(intc0->dev,
+			"%s: Resolved INTC0 input %u route to parent via %d\n",
+			__func__, input, rc);
+	}
+
+	return rc;
+}
+
+/**
+ * aspeed_intc0_resolve_route - Determine the necessary interrupt output at intc1
+ * @c0domain: The pointer to intc0's irq_domain
+ * @nc1outs: The number of valid intc1 outputs available for the input
+ * @c1outs: The array of available intc1 output indices for the input
+ * @nc1ranges: The number of interrupt range entries for intc1
+ * @c1ranges: The array of configured intc1 interrupt ranges
+ * @resolved: The fully resolved range entry after applying the resolution
+ *            algorithm
+ *
+ * Returns: The intc1 route index associated with the intc1 output identified in
+ * @resolved on success. Otherwise, a negative errno value.
+ *
+ * The AST2700 interrupt architecture allows any peripheral interrupt source
+ * to be routed to one of up to four processors running in the SoC. A processor
+ * binding a driver for a peripheral that requests an interrupt is (without
+ * further design and effort) the destination for the requested interrupt.
+ *
+ * Routing a peripheral interrupt to its destination processor requires
+ * coordination between INTC0 on the CPU die and one or more INTC1 instances.
+ * At least one INTC1 instance exists in the SoC on the IO-die, however up
+ * to two more instances may be integrated via LTPI (LVDS Tunneling Protocol
+ * & Interface).
+ *
+ * Between the multiple destinations, various route constraints, and the
+ * devicetree binding design, some information that's needed at INTC1 instances
+ * to route inbound interrupts correctly to the destination processor is only
+ * available at INTC0.
+ *
+ * aspeed_intc0_resolve_route() is to be invoked by INTC1 driver instances to
+ * perform the route resolution. The implementation in INTC0 allows INTC0 to
+ * encapsulate the information used to perform route selection, and provides it
+ * with an opportunity to apply policy as part of the selection process. Such
+ * policy may, for instance, choose to de-prioritise some interrupts destined
+ * for the PSP (Primary Service Processor) GIC.
+ */
+int aspeed_intc0_resolve_route(const struct irq_domain *c0domain, size_t nc1outs,
+			       const aspeed_intc_output_t c1outs[static nc1outs],
+			       size_t nc1ranges,
+			       const struct aspeed_intc_interrupt_range c1ranges[static nc1ranges],
+			       struct aspeed_intc_interrupt_range *resolved)
+{
+	struct aspeed_intc0 *intc0;
+	struct fwnode_handle *parent_fwnode;
+	int ret;
+
+	if (!c0domain || !resolved)
+		return -EINVAL;
+
+	if (nc1outs > INT_MAX)
+		return -EINVAL;
+
+	if (nc1outs == 0 || nc1ranges == 0)
+		return -ENODEV;
+
+	if (!fwnode_device_is_compatible(c0domain->fwnode,
+					 "aspeed,ast2700-intc0-ic"))
+		return -ENODEV;
+
+	intc0 = c0domain->host_data;
+	if (!intc0)
+		return -EINVAL;
+
+	parent_fwnode = of_fwnode_handle(intc0->parent);
+
+	for (size_t i = 0; i < nc1outs; i++) {
+		aspeed_intc_output_t c1o = c1outs[i];
+
+		if (c1o == AST2700_INTC_INVALID_ROUTE) {
+			dev_dbg(intc0->dev, "%s: Invalid output at route index %zu\n",
+				__func__, i);
+			continue;
+		}
+
+		dev_dbg(intc0->dev, "%s: Have output %u for route index %zu\n",
+			__func__, c1o, i);
+
+		for (size_t j = 0; j < nc1ranges; j++) {
+			struct aspeed_intc_interrupt_range c1r = c1ranges[j];
+			u32 input;
+
+			dev_dbg(intc0->dev,
+				"%s: Inspecting candidate range %zu starting at %u for %u\n",
+				__func__, j, c1r.start, c1r.count);
+
+			/*
+			 * Range match for intc1 output pin
+			 *
+			 * Assume a failed match is still a match for the purpose of testing,
+			 * saves a bunch of mess in the test fixtures
+			 */
+			if (!(c0domain == irq_find_matching_fwspec(&c1r.upstream,
+								   c0domain->bus_token) ||
+			      IS_ENABLED(CONFIG_ASPEED_AST2700_INTC_TEST))) {
+				dev_dbg(intc0->dev, "%s: Parent mismatch for candidate range %zu\n",
+					__func__, j);
+				continue;
+			}
+
+			ret = resolve_input_from_child_ranges(intc0, &c1r, c1o, &input);
+			if (ret) {
+				if (ret == -ENOENT)
+					dev_dbg(intc0->dev,
+						"%s: Output %u not in candidate range %zu starting at %u for %u\n",
+						__func__, c1o, j, c1r.start, c1r.count);
+				continue;
+			}
+			dev_dbg(intc0->dev,
+				"%s: Resolved INTC0 input to %u using candidate range %zu: [%u, %u)\n",
+				__func__, input, j, c1r.start, c1r.start + c1r.count);
+
+			/*
+			 * INTC1 should never request routes for peripheral interrupt sources
+			 * directly attached to INTC0.
+			 */
+			if (input < GIC_P2P_SPI_END) {
+				dev_dbg(intc0->dev,
+					"%s: Invalid range specification at index %zu routed INTC1 output to unreachable INTC0 input\n",
+					__func__, j);
+				continue;
+			}
+
+			ret = resolve_parent_route_for_input(intc0, parent_fwnode, input, NULL);
+			if (ret < 0)
+				continue;
+
+			/* Route resolution succeeded */
+			resolved->start = c1o;
+			resolved->count = 1;
+			resolved->upstream = c1r.upstream;
+			resolved->upstream.param[0] = input;
+			dev_dbg(intc0->dev,
+				"%s: Route resolution selected INTC1 output %u via index %zu\n",
+				__func__, c1o, i);
+			/* Cast protected by prior test against nc1outs */
+			return (int)i;
+		}
+	}
+
+	ret = -EHOSTUNREACH;
+	return ret;
+}
+EXPORT_SYMBOL_GPL(aspeed_intc0_resolve_route);
+
+static int aspeed_intc0_irq_domain_map(struct irq_domain *domain,
+				       unsigned int irq, irq_hw_number_t hwirq)
+{
+	if (hwirq < GIC_P2P_SPI_END)
+		irq_set_chip_and_handler(irq, &linear_intr_irq_chip,
+					 handle_level_irq);
+	else if (hwirq < INTM_BASE)
+		return -EINVAL;
+	else if (hwirq < SWINT_BASE)
+		irq_set_chip_and_handler(irq, &aspeed_intm_chip,
+					 handle_level_irq);
+	else if (hwirq < INT0_NUM)
+		irq_set_chip_and_handler(irq, &aspeed_swint_chip,
+					 handle_level_irq);
+	else
+		return -EINVAL;
+
+	irq_set_chip_data(irq, domain->host_data);
+	return 0;
+}
+
+static int aspeed_intc0_irq_domain_translate(struct irq_domain *domain,
+					     struct irq_fwspec *fwspec,
+					     unsigned long *hwirq,
+					     unsigned int *type)
+{
+	if (fwspec->param_count != 1)
+		return -EINVAL;
+
+	*hwirq = fwspec->param[0];
+	*type = IRQ_TYPE_NONE;
+	return 0;
+}
+
+static int aspeed_intc0_irq_domain_alloc(struct irq_domain *domain,
+					 unsigned int virq,
+					 unsigned int nr_irqs, void *data)
+{
+	struct aspeed_intc0 *intc0 = domain->host_data;
+	struct aspeed_intc_interrupt_range resolved;
+	struct irq_fwspec *fwspec = data;
+	struct irq_fwspec parent_fwspec;
+	struct irq_chip *chip;
+	unsigned long hwirq;
+	unsigned int type;
+	int ret;
+
+	ret = aspeed_intc0_irq_domain_translate(domain, fwspec, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	if (hwirq >= GIC_P2P_SPI_END && hwirq < INT_NUM)
+		return -EINVAL;
+
+	if (hwirq < INTM_BASE)
+		chip = &linear_intr_irq_chip;
+	else if (hwirq < SWINT_BASE)
+		chip = &aspeed_intm_chip;
+	else
+		chip = &aspeed_swint_chip;
+
+	ret = resolve_parent_route_for_input(intc0, domain->parent->fwnode,
+					     (u32)hwirq, &resolved);
+	if (ret)
+		return ret;
+
+	parent_fwspec = resolved.upstream;
+	ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
+					   &parent_fwspec);
+	if (ret)
+		return ret;
+
+	for (int i = 0; i < nr_irqs; ++i, ++hwirq, ++virq) {
+		ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip,
+						    domain->host_data);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int aspeed_intc0_irq_domain_activate(struct irq_domain *domain,
+					    struct irq_data *data, bool reserve)
+{
+	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
+
+	if (data->hwirq < INT_NUM) {
+		int bank = data->hwirq / 32;
+		int bit = data->hwirq % 32;
+		u32 mask = BIT(bit);
+		int route;
+
+		route = resolve_parent_route_for_input(intc0,
+						       intc0->local->parent->fwnode,
+						       data->hwirq, NULL);
+		if (route < 0)
+			return route;
+
+		guard(raw_spinlock_irqsave)(&intc0->intc_lock);
+		for (int i = 0; i < 3; i++) {
+			void __iomem *sel = intc0->base + 0x200 + bank * 4 + 0x100 * i;
+			u32 reg = readl(sel);
+
+			if (route & BIT(i))
+				reg |= mask;
+			else
+				reg &= ~mask;
+
+			writel(reg, sel);
+			if (readl(sel) != reg)
+				return -EACCES;
+		}
+	} else if (data->hwirq < INT0_NUM) {
+		return 0;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops aspeed_intc0_ic_irq_domain_ops = {
+	.translate = aspeed_intc0_irq_domain_translate,
+	.alloc = aspeed_intc0_irq_domain_alloc,
+	.free = irq_domain_free_irqs_common,
+	.map = aspeed_intc0_irq_domain_map,
+	.activate = aspeed_intc0_irq_domain_activate,
+};
+
+static void aspeed_intc0_disable_swint(struct aspeed_intc0 *intc0)
+{
+	writel(0, intc0->base + INTC0_SWINT_IER);
+}
+
+static void aspeed_intc0_disable_intbank(struct aspeed_intc0 *intc0)
+{
+	int i, j;
+
+	for (i = 0; i < INTC0_INTBANK_GROUPS; i++) {
+		for (j = 0; j < INTC0_INTBANKS_PER_GRP; j++) {
+			u32 base = INTC0_INTBANKX_IER + (0x100 * i) + (0x10 * j);
+
+			writel(0, intc0->base + base);
+		}
+	}
+}
+
+static void aspeed_intc0_disable_intm(struct aspeed_intc0 *intc0)
+{
+	int i;
+
+	for (i = 0; i < INTC0_INTM_BANK_NUM; i++)
+		writel(0, intc0->base + INTC0_INTMX_IER + (0x10 * i));
+}
+
+static int aspeed_intc0_ic_probe(struct platform_device *pdev,
+				 struct device_node *parent)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct irq_domain *parent_domain;
+	struct aspeed_intc0 *intc0;
+	int ret;
+
+	if (!parent) {
+		pr_err("missing parent interrupt node\n");
+		return -ENODEV;
+	}
+
+	intc0 = devm_kzalloc(&pdev->dev, sizeof(*intc0), GFP_KERNEL);
+	if (!intc0)
+		return -ENOMEM;
+
+	intc0->dev = &pdev->dev;
+	intc0->parent = parent;
+	intc0->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(intc0->base))
+		return PTR_ERR(intc0->base);
+
+	aspeed_intc0_disable_swint(intc0);
+	aspeed_intc0_disable_intbank(intc0);
+	aspeed_intc0_disable_intm(intc0);
+
+	raw_spin_lock_init(&intc0->intc_lock);
+
+	parent_domain = irq_find_host(parent);
+	if (!parent_domain) {
+		pr_err("unable to obtain parent domain\n");
+		return -ENODEV;
+	}
+
+	if (!of_device_is_compatible(parent, "arm,gic-v3"))
+		return -ENODEV;
+
+	intc0->local = irq_domain_create_hierarchy(parent_domain, 0, INT0_NUM,
+						   of_fwnode_handle(node),
+						   &aspeed_intc0_ic_irq_domain_ops,
+						   intc0);
+	if (!intc0->local)
+		return -ENOMEM;
+
+	ret = aspeed_intc_populate_ranges(&pdev->dev, &intc0->ranges);
+	if (ret < 0) {
+		irq_domain_remove(intc0->local);
+		return ret;
+	}
+
+	return 0;
+}
+
+IRQCHIP_PLATFORM_DRIVER_BEGIN(ast2700_intc0)
+IRQCHIP_MATCH("aspeed,ast2700-intc0-ic", aspeed_intc0_ic_probe)
+IRQCHIP_PLATFORM_DRIVER_END(ast2700_intc0)
+
+#ifdef CONFIG_ASPEED_AST2700_INTC_TEST
+#include "irq-ast2700-intc0-test.c"
+#endif
diff --git a/drivers/irqchip/irq-ast2700-intc1.c b/drivers/irqchip/irq-ast2700-intc1.c
new file mode 100644
index 000000000000..51371cc57c5c
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700-intc1.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Aspeed AST2700 Interrupt Controller.
+ *
+ *  Copyright (C) 2023 ASPEED Technology Inc.
+ */
+
+#include "linux/dev_printk.h"
+#include "linux/device/devres.h"
+#include "linux/property.h"
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/spinlock.h>
+
+#include "irq-ast2700.h"
+
+#define INTC1_IER 0x100
+#define INTC1_ISR 0x104
+#define INTC1_IRQS_PER_BANK 32
+#define INTC1_BANK_NUM 6
+#define INTC1_ROUTE_NUM 7
+
+struct aspeed_intc1 {
+	struct device *dev;
+	void __iomem *base;
+	raw_spinlock_t intc_lock;
+	struct irq_domain *local;
+	struct irq_domain *upstream;
+	struct aspeed_intc_interrupt_ranges ranges;
+};
+
+static void aspeed_intc1_disable_int(struct aspeed_intc1 *intc1)
+{
+	for (int i = 0; i < INTC1_BANK_NUM; i++)
+		writel(0x0, intc1->base + INTC1_IER + (0x10 * i));
+}
+
+static void aspeed_intc1_ic_irq_handler(struct irq_desc *desc)
+{
+	struct aspeed_intc1 *intc1 = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	unsigned long bit, status;
+
+	chained_irq_enter(chip, desc);
+
+	for (int bank = 0; bank < INTC1_BANK_NUM; bank++) {
+		status = readl(intc1->base + INTC1_ISR + (0x10 * bank));
+		if (!status)
+			continue;
+
+		for_each_set_bit(bit, &status, INTC1_IRQS_PER_BANK) {
+			generic_handle_domain_irq(intc1->local,
+						  (bank * INTC1_IRQS_PER_BANK) +
+							  bit);
+			writel(BIT(bit),
+			       intc1->base + INTC1_ISR + (0x10 * bank));
+		}
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void aspeed_intc1_irq_mask(struct irq_data *data)
+{
+	struct aspeed_intc1 *intc1 = irq_data_get_irq_chip_data(data);
+	int bank = data->hwirq / INTC1_IRQS_PER_BANK;
+	int bit = data->hwirq % INTC1_IRQS_PER_BANK;
+	unsigned int mask;
+
+	guard(raw_spinlock_irqsave)(&intc1->intc_lock);
+	mask = readl(intc1->base + INTC1_IER + (0x10 * bank)) & ~BIT(bit);
+	writel(mask, intc1->base + INTC1_IER + (0x10 * bank));
+}
+
+static void aspeed_intc1_irq_unmask(struct irq_data *data)
+{
+	struct aspeed_intc1 *intc1 = irq_data_get_irq_chip_data(data);
+	int bank = data->hwirq / INTC1_IRQS_PER_BANK;
+	int bit = data->hwirq % INTC1_IRQS_PER_BANK;
+	unsigned int unmask;
+
+	guard(raw_spinlock_irqsave)(&intc1->intc_lock);
+	unmask = readl(intc1->base + INTC1_IER + (0x10 * bank)) | BIT(bit);
+	writel(unmask, intc1->base + INTC1_IER + (0x10 * bank));
+}
+
+static struct irq_chip aspeed_intc_chip = {
+	.name = "ASPEED INTC1",
+	.irq_mask = aspeed_intc1_irq_mask,
+	.irq_unmask = aspeed_intc1_irq_unmask,
+};
+
+static int aspeed_intc1_irq_domain_translate(struct irq_domain *domain,
+					     struct irq_fwspec *fwspec,
+					     unsigned long *hwirq,
+					     unsigned int *type)
+{
+	if (fwspec->param_count != 1)
+		return -EINVAL;
+
+	*hwirq = fwspec->param[0];
+	*type = IRQ_TYPE_LEVEL_HIGH;
+	return 0;
+}
+
+static int aspeed_intc1_ic_map_irq_domain(struct irq_domain *domain,
+					  unsigned int irq,
+					  irq_hw_number_t hwirq)
+{
+	irq_domain_set_info(domain, irq, hwirq, &aspeed_intc_chip,
+			    domain->host_data, handle_level_irq, NULL, NULL);
+	return 0;
+}
+
+#define INTC1_IN_NUM 192
+
+/*
+ * In-bound interrupts are progressively merged into one out-bound interrupt in
+ * groups of 32. Apply this fact to compress the route table in corresponding
+ * groups of 32.
+ */
+static const aspeed_intc_output_t aspeed_intc1_routes[INTC1_IN_NUM / 32][INTC1_ROUTE_NUM] = {
+	[0] = {
+		[0b000] = 0,
+		[0b001] = AST2700_INTC_INVALID_ROUTE, /* path not verified */
+		[0b010] = 10,
+		[0b011] = 20,
+		[0b100] = 30,
+		[0b101] = 40,
+		[0b110] = 50,
+	},
+	[1] = {
+		[0b000] = 1,
+		[0b001] = AST2700_INTC_INVALID_ROUTE,
+		[0b010] = 11,
+		[0b011] = 21,
+		[0b100] = 31,
+		[0b101] = 41,
+		[0b110] = 50,
+	},
+	[2] = {
+		[0b000] = 2,
+		[0b001] = AST2700_INTC_INVALID_ROUTE,
+		[0b010] = 12,
+		[0b011] = 22,
+		[0b100] = 32,
+		[0b101] = 42,
+		[0b110] = 50,
+	},
+	[3] = {
+		[0b000] = 3,
+		[0b001] = AST2700_INTC_INVALID_ROUTE,
+		[0b010] = 13,
+		[0b011] = 23,
+		[0b100] = 33,
+		[0b101] = 43,
+		[0b110] = 50,
+	},
+	[4] = {
+		[0b000] = 4,
+		[0b001] = AST2700_INTC_INVALID_ROUTE,
+		[0b010] = 14,
+		[0b011] = 24,
+		[0b100] = 34,
+		[0b101] = 44,
+		[0b110] = 50,
+	},
+	[5] = {
+		[0b000] = 5,
+		[0b001] = AST2700_INTC_INVALID_ROUTE,
+		[0b010] = 15,
+		[0b011] = 25,
+		[0b100] = 35,
+		[0b101] = 45,
+		[0b110] = 50,
+	},
+};
+
+#define INTC1_BOOTMCU_ROUTE 0b110
+
+static int aspeed_intc1_parent_is_bootmcu(const struct irq_domain *upstream)
+{
+	if (!upstream || !upstream->fwnode)
+		return 0;
+
+	return fwnode_device_is_compatible(upstream->fwnode, "riscv,aplic");
+}
+
+static int aspeed_intc1_irq_domain_activate(struct irq_domain *domain,
+					    struct irq_data *data, bool reserve)
+{
+	struct aspeed_intc1 *intc1 = irq_data_get_irq_chip_data(data);
+	int bank = data->hwirq / INTC1_IRQS_PER_BANK;
+	struct aspeed_intc_interrupt_range resolved;
+	int bit = data->hwirq % INTC1_IRQS_PER_BANK;
+	u32 mask = BIT(bit);
+	int rc;
+
+	if (WARN_ON_ONCE((data->hwirq >> 5) >= ARRAY_SIZE(aspeed_intc1_routes)))
+		return -EINVAL;
+
+	dev_dbg(intc1->dev, "Activation request for hwirq %lu in domain %s\n",
+		data->hwirq, domain->name);
+
+	/*
+	 * outpin may be an error if the upstream is the BootMCU APLIC node, or
+	 * anything except a valid intc0 driver instance
+	 */
+	rc = aspeed_intc0_resolve_route(intc1->upstream, INTC1_ROUTE_NUM,
+					aspeed_intc1_routes[data->hwirq >> 5],
+					intc1->ranges.nranges,
+					intc1->ranges.ranges, &resolved);
+	if (rc < 0) {
+		if (!aspeed_intc1_parent_is_bootmcu(intc1->upstream)) {
+			dev_warn(intc1->dev,
+				 "Failed to resolve interrupt route for hwirq %lu in domain %s\n",
+				 data->hwirq, domain->name);
+			return rc;
+		}
+		rc = INTC1_BOOTMCU_ROUTE;
+	}
+
+	guard(raw_spinlock_irqsave)(&intc1->intc_lock);
+	/* Route selector uses 3 bits across the selector registers. */
+	for (int i = 0; i < 3; i++) {
+		void __iomem *sel = intc1->base + 0x80 + bank * 4 + 0x20 * i;
+		u32 reg = readl(sel);
+
+		if (rc & BIT(i))
+			reg |= mask;
+		else
+			reg &= ~mask;
+
+		writel(reg, sel);
+		if (readl(sel) != reg)
+			return -EACCES;
+	}
+
+	dev_dbg(intc1->dev,
+		"Routed hwirq %lu in domain %s to output %u via route %d\n",
+		data->hwirq, domain->name, resolved.start, rc);
+
+	return 0;
+}
+
+static const struct irq_domain_ops aspeed_intc1_ic_irq_domain_ops = {
+	.map = aspeed_intc1_ic_map_irq_domain,
+	.translate = aspeed_intc1_irq_domain_translate,
+	.activate = aspeed_intc1_irq_domain_activate,
+};
+
+static void aspeed_intc1_request_interrupts(struct aspeed_intc1 *intc1)
+{
+	unsigned int i;
+
+	for (i = 0; i < intc1->ranges.nranges; i++) {
+		struct aspeed_intc_interrupt_range *r =
+			&intc1->ranges.ranges[i];
+
+		if (intc1->upstream !=
+		    irq_find_matching_fwspec(&r->upstream,
+					     intc1->upstream->bus_token))
+			continue;
+
+		for (u32 k = 0; k < r->count; k++) {
+			struct of_phandle_args parent_irq;
+			int irq;
+
+			parent_irq.np = to_of_node(r->upstream.fwnode);
+			parent_irq.args_count = 1;
+			parent_irq.args[0] =
+				intc1->ranges.ranges[i].upstream.param[0] + k;
+
+			irq = irq_create_of_mapping(&parent_irq);
+			if (!irq)
+				continue;
+
+			irq_set_chained_handler_and_data(irq,
+							 aspeed_intc1_ic_irq_handler, intc1);
+			dev_dbg(intc1->dev, "Mapped irq %d\n", parent_irq.args[0]);
+		}
+	}
+}
+
+static int aspeed_intc1_ic_probe(struct platform_device *pdev,
+				 struct device_node *parent)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct aspeed_intc1 *intc1;
+	struct irq_domain *host;
+	int ret;
+
+	if (!parent) {
+		dev_err(&pdev->dev, "missing parent interrupt node\n");
+		return -ENODEV;
+	}
+
+	if (!of_device_is_compatible(parent, "aspeed,ast2700-intc0-ic"))
+		return -ENODEV;
+
+	host = irq_find_host(parent);
+	if (!host)
+		return -ENODEV;
+
+	intc1 = devm_kzalloc(&pdev->dev, sizeof(*intc1), GFP_KERNEL);
+	if (!intc1)
+		return -ENOMEM;
+
+	intc1->dev = &pdev->dev;
+	intc1->upstream = host;
+	intc1->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(intc1->base))
+		return PTR_ERR(intc1->base);
+
+	aspeed_intc1_disable_int(intc1);
+
+	raw_spin_lock_init(&intc1->intc_lock);
+
+	intc1->local = irq_domain_create_linear(of_fwnode_handle(node),
+						INTC1_BANK_NUM * INTC1_IRQS_PER_BANK,
+						&aspeed_intc1_ic_irq_domain_ops, intc1);
+	if (!intc1->local)
+		return -ENOMEM;
+
+	ret = aspeed_intc_populate_ranges(&pdev->dev, &intc1->ranges);
+	if (ret < 0) {
+		irq_domain_remove(intc1->local);
+		return ret;
+	}
+
+	aspeed_intc1_request_interrupts(intc1);
+
+	return 0;
+}
+
+IRQCHIP_PLATFORM_DRIVER_BEGIN(ast2700_intc1)
+IRQCHIP_MATCH("aspeed,ast2700-intc1-ic", aspeed_intc1_ic_probe)
+IRQCHIP_PLATFORM_DRIVER_END(ast2700_intc1)
diff --git a/drivers/irqchip/irq-ast2700.c b/drivers/irqchip/irq-ast2700.c
new file mode 100644
index 000000000000..269d743207ae
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Aspeed Interrupt Controller.
+ *
+ *  Copyright (C) 2023 ASPEED Technology Inc.
+ */
+#include "irq-ast2700.h"
+
+#include <linux/dev_printk.h>
+#include <linux/device/devres.h>
+
+int aspeed_intc_populate_ranges(struct device *dev,
+				struct aspeed_intc_interrupt_ranges *ranges)
+{
+	struct aspeed_intc_interrupt_range *arr;
+	const __be32 *pvs, *pve;
+	struct device_node *dn;
+	int len;
+
+	if (!dev || !ranges)
+		return -EINVAL;
+
+	dn = dev->of_node;
+
+	pvs = of_get_property(dn, "aspeed,interrupt-ranges", &len);
+	if (!pvs)
+		return -EINVAL;
+
+	if (len % sizeof(__be32))
+		return -EINVAL;
+
+	/* Over-estimate the range entry count for now */
+	ranges->ranges = devm_kmalloc_array(dev, (len / (3 * sizeof(__be32))),
+					    sizeof(*ranges->ranges),
+					    GFP_KERNEL);
+	if (!ranges->ranges)
+		return -ENOMEM;
+
+	pve = pvs + (len / sizeof(__be32));
+	for (unsigned int i = 0; pve - pvs >= 3; i++) {
+		struct aspeed_intc_interrupt_range *r;
+		struct device_node *target;
+		u32 target_cells;
+
+		target = of_find_node_by_phandle(be32_to_cpu(pvs[2]));
+		if (!target)
+			return -EINVAL;
+
+		if (of_property_read_u32(target, "#interrupt-cells",
+					 &target_cells)) {
+			of_node_put(target);
+			return -EINVAL;
+		}
+
+		if (!target_cells || target_cells > IRQ_DOMAIN_IRQ_SPEC_PARAMS) {
+			of_node_put(target);
+			return -EINVAL;
+		}
+
+		if (pve - pvs < 3 + target_cells) {
+			of_node_put(target);
+			return -EINVAL;
+		}
+
+		r = &ranges->ranges[i];
+		r->start = be32_to_cpu(pvs[0]);
+		r->count = be32_to_cpu(pvs[1]);
+
+		{
+			struct of_phandle_args args = {
+				.np = target,
+				.args_count = target_cells,
+			};
+
+			for (u32 j = 0; j < target_cells; j++)
+				args.args[j] = be32_to_cpu(pvs[3 + j]);
+
+			of_phandle_args_to_fwspec(target, args.args,
+						  args.args_count,
+						  &r->upstream);
+		}
+
+		if (target_cells >= 1)
+			dev_dbg(dev,
+				"Mapped %u outputs from %u to %u on parent %s",
+				r->count, r->start, r->upstream.param[0], target->full_name);
+		else
+			dev_dbg(dev,
+				"Registered interrupt range from %u for count %u\n",
+				r->start, r->count);
+
+		of_node_put(target);
+		pvs += 3 + target_cells;
+		ranges->nranges++;
+	}
+
+	/* Re-fit the range array now we know the entry count */
+	arr = devm_krealloc_array(dev, ranges->ranges, ranges->nranges,
+				  sizeof(*ranges->ranges), GFP_KERNEL);
+	if (!arr)
+		return -ENOMEM;
+	ranges->ranges = arr;
+
+	return 0;
+}
diff --git a/drivers/irqchip/irq-ast2700.h b/drivers/irqchip/irq-ast2700.h
new file mode 100644
index 000000000000..56dbb1c88b11
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *  Aspeed AST2700 Interrupt Controller.
+ *
+ *  Copyright (C) 2023 ASPEED Technology Inc.
+ */
+#ifndef DRIVERS_IRQCHIP_AST2700
+#define DRIVERS_IRQCHIP_AST2700
+
+#include <linux/device.h>
+#include <linux/irqdomain.h>
+
+#define AST2700_INTC_INVALID_ROUTE (~0U)
+
+struct aspeed_intc_interrupt_range {
+	u32 start;
+	u32 count;
+	struct irq_fwspec upstream;
+};
+
+struct aspeed_intc_interrupt_ranges {
+	struct aspeed_intc_interrupt_range *ranges;
+	unsigned int nranges;
+};
+
+int aspeed_intc_populate_ranges(struct device *dev,
+				struct aspeed_intc_interrupt_ranges *ranges);
+
+typedef u32 aspeed_intc_output_t;
+
+int aspeed_intc0_resolve_route(
+	const struct irq_domain *c0domain, size_t nc1outs,
+	const aspeed_intc_output_t c1outs[static nc1outs], size_t nc1ranges,
+	const struct aspeed_intc_interrupt_range c1ranges[static nc1ranges],
+	struct aspeed_intc_interrupt_range *resolved);
+
+#endif

-- 
2.34.1
Re: [PATCH 2/4] irqchip/ast2700-intcx: Add AST2700 INTC0/INTC1 support
Posted by Thomas Gleixner 2 days, 6 hours ago
On Thu, Feb 05 2026 at 14:07, Ryan Chen wrote:
> @@ -88,6 +88,7 @@ obj-$(CONFIG_MVEBU_PIC)			+= irq-mvebu-pic.o
>  obj-$(CONFIG_MVEBU_SEI)			+= irq-mvebu-sei.o
>  obj-$(CONFIG_LS_EXTIRQ)			+= irq-ls-extirq.o
>  obj-$(CONFIG_LS_SCFG_MSI)		+= irq-ls-scfg-msi.o
> +obj-$(CONFIG_ASPEED_AST2700_INTC)	+= irq-ast2700.o irq-ast2700-intc0.o irq-ast2700-intc1.o
>  obj-$(CONFIG_ARCH_ASPEED)		+= irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o
>  obj-$(CONFIG_ARCH_ASPEED)		+= irq-aspeed-intc.o
>  obj-$(CONFIG_STM32MP_EXTI)		+= irq-stm32mp-exti.o
> diff --git a/drivers/irqchip/irq-ast2700-intc0-test.c b/drivers/irqchip/irq-ast2700-intc0-test.c

How is this kunit test supposed to be built?

Also split this kunit thing out into a separate patch. It is not
relevant for the functional part.

> new file mode 100644
> index 000000000000..d6bc19676b2e
> --- /dev/null
> +++ b/drivers/irqchip/irq-ast2700-intc0-test.c
> @@ -0,0 +1,474 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + *  Copyright (C) 2026 Code Construct
> + */
> +#include <kunit/test.h>
> +#include "irq-ast2700.h"
> +
> +static void aspeed_intc0_resolve_route_bad_args(struct kunit *test)
> +{
> +	static const struct aspeed_intc_interrupt_range c1ranges[] = { 0 };
> +	static const aspeed_intc_output_t c1outs[] = { 0 };
> +	struct aspeed_intc_interrupt_range resolved;
> +	const struct irq_domain c0domain = { 0 };
> +

Pointless newline

> +	int rc;
> +
> +	rc = aspeed_intc0_resolve_route(NULL, 0, c1outs, 0, c1ranges, NULL);
> +	KUNIT_EXPECT_EQ(test, rc, -EINVAL);
> +
> +	rc = aspeed_intc0_resolve_route(&c0domain, 0, c1outs,
> +					ARRAY_SIZE(c1ranges), c1ranges,
> +					&resolved);
> +	KUNIT_EXPECT_EQ(test, rc, -ENODEV);
> +
> +	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
> +					0, c1ranges, &resolved);
> +	KUNIT_EXPECT_EQ(test, rc, -ENODEV);
> +}
> +
> +static int
> +arm_gicv3_fwnode_read_string_array(const struct fwnode_handle *fwnode_handle,
> +				   const char *propname, const char **val,
> +				   size_t nval)

Please use the full 100 character you have available and avoid extra
line breaks. It fits nicely into two lines:

static int arm_gicv3_fwnode_read_string_array(const struct fwnode_handle *fwnode_handle, 
			                      const char *propname, const char **val, size_t nval)

There is also no real point to have these overly long function and
argument names.

> +#include <asm-generic/errno.h>

That's wrong. Include <linux/errno.h>

> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +#include "irq-ast2700.h"

Missing newline

> +#define INT_NUM 480
> +#define INTM_NUM 50
> +#define SWINT_NUM 16
> +
> +#define INTM_BASE (INT_NUM)
> +#define SWINT_BASE (INT_NUM + INTM_NUM)
> +#define INT0_NUM (INT_NUM + INTM_NUM + SWINT_NUM)
> +
> +#define GIC_P2P_SPI_END 128
> +
> +#define INTC0_SWINT_IER 0x10
> +#define INTC0_SWINT_ISR 0x14
> +#define INTC0_INTBANKX_IER 0x1000
> +#define INTC0_INTBANK_GROUPS 11
> +#define INTC0_INTBANKS_PER_GRP 3
> +#define INTC0_INTMX_IER 0x1b00
> +#define INTC0_INTMX_ISR 0x1b04
> +#define INTC0_INTM_BANK_NUM 3
> +#define INTM_IRQS_PER_BANK 10

If you make these defines tabular and they become readable:

#define INT_NUM			480
#define INTM_NUM		50
...
#define INTM_BASE 		(INT_NUM)
...
#define GIC_P2P_SPI_END		128
...
#define INTC0_SWINT_IER		0x10

See?

> +struct aspeed_intc0 {
> +	struct device *dev;
> +	void __iomem *base;
> +	raw_spinlock_t intc_lock;
> +	struct irq_domain *local;
> +	struct device_node *parent;
> +	struct aspeed_intc_interrupt_ranges ranges;
> +};

https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#struct-declarations-and-initializers

I pointed you to that documentation before. Do I really have to remind
you every couple of week?

> +
> +static void aspeed_swint_irq_mask(struct irq_data *data)
> +{
> +	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
> +	int bit = data->hwirq - SWINT_BASE;
> +	unsigned int mask;
> +
> +	guard(raw_spinlock_irqsave)(&intc0->intc_lock);

s/_irqsave// Interrupts are disabled when this is invoked.

> +	mask = readl(intc0->base + INTC0_SWINT_IER) & ~BIT(bit);
> +	writel(mask, intc0->base + INTC0_SWINT_IER);
> +	irq_chip_mask_parent(data);
> +}
> +
> +static void aspeed_swint_irq_unmask(struct irq_data *data)
> +{
> +	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
> +	int bit = data->hwirq - SWINT_BASE;
> +	unsigned int unmask;
> +
> +	guard(raw_spinlock_irqsave)(&intc0->intc_lock);
> +	unmask = readl(intc0->base + INTC0_SWINT_IER) | BIT(bit);

These unmask/mask variable are simply not helpful. What's wrong with
naming them 'ier' because that's what this is about. And while at it the
data type for hardware related variables is u32 not unsigned int to make
it clear.

> +static struct irq_chip aspeed_swint_chip = {
> +	.name = "ast2700-swint",
> +	.irq_eoi = aspeed_swint_irq_eoi,
> +	.irq_mask = aspeed_swint_irq_mask,
> +	.irq_unmask = aspeed_swint_irq_unmask,
> +	.irq_set_affinity = irq_chip_set_affinity_parent,
> +	.flags = IRQCHIP_SET_TYPE_MASKED,

See above

> +
> +#define INTC0_IN_NUM 480
> +#define INTC0_ROUTE_NUM 5

Those should be at the top of the file next to the other constants.

> +static const aspeed_intc_output_t aspeed_intc0_routes[INTC0_IN_NUM / 32][INTC0_ROUTE_NUM] = {
> +	[0] = {
> +		[0b000] = 0,
> +		[0b001] = 256,
> +		[0b010] = 426,
> +		[0b011] = AST2700_INTC_INVALID_ROUTE,
> +		[0b100] = AST2700_INTC_INVALID_ROUTE,

Seriously? What's the point of this binary notation and the insane
amount of space this table occupies?

	[0] = {   0, 256, 426, AST2700_INTC_INVALID_ROUTE, AST2700_INTC_INVALID_ROUTE },
	[1] = {  32, 288, 458, AST2700_INTC_INVALID_ROUTE, AST2700_INTC_INVALID_ROUTE },
	[4] = { 128, 384, 554, 160, 176 },
        ...


> +
> +#define INTC0_INTM_NUM 50
> +
> +static const aspeed_intc_output_t
> +	aspeed_intc0_intm_routes[INTC0_INTM_NUM / 10] = {

pointless line break

> +		[0] = 192, /* INTM00 ~ INTM09 */
> +		[1] = 416, /* INTM10 ~ INTM19 */
> +		[2] = 586, /* INTM20 ~ INTM29 */
> +		[3] = 208, /* INTM30 ~ INTM39 */
> +		[4] = 224, /* INTM40 ~ INTM49 */
> +	};
> +
> +static bool range_contains_element(u32 start, u32 count, u32 value)

in_range32() provides that already

> +{
> +	if (WARN_ON_ONCE((U32_MAX - count) < start))
> +		return false;
> +
> +	return value >= start && value < start + count;
> +}
> +
> +static int
> +resolve_input_from_child_ranges(const struct aspeed_intc0 *intc0,
> +				const struct aspeed_intc_interrupt_range *range,
> +				u32 outpin, u32 *input)
> +{
> +	u32 offset;
> +	u32 base;

One line

> +
> +	if (!range_contains_element(range->start, range->count, outpin))
> +		return -ENOENT;
> +
> +	if (range->upstream.param_count == 0)
> +		return -EINVAL;
> +
> +	base = range->upstream.param[0];
> +	offset = outpin - range->start;
> +	if ((U32_MAX - offset) < base) {

        if (!in_range32(...)


> +		dev_warn(intc0->dev,
> +			 "%s: Arithmetic overflow for input derivation: %u + %u\n",

Pointless line break. Please fix them all over the place.

> +			 __func__, base, offset);
> +		return -EINVAL;
> +	}
> +
> +	*input = base + offset;
> +	return 0;
> +static int resolve_parent_route_for_input(const struct aspeed_intc0 *intc0,
> +					  const struct fwnode_handle *parent, u32 input,
> +					  struct aspeed_intc_interrupt_range *resolved)
> +{
> +	aspeed_intc_output_t c0o;
> +	int rc = -ENOENT;
> +
> +	if (input < INT_NUM) {
> +		bool found;
> +
> +		dev_dbg(intc0->dev, "%s: Resolving parent route for linear input %u\n",
> +			__func__, input);

Do you really still need all those debug prints or are you trusting your
code by now?

If they still are considered valuable then shorten them in a sensible
way so they nicely hide in the code instead of cluttering it to the
point of making it unreadable.

> +{
> +	struct aspeed_intc0 *intc0;
> +	struct fwnode_handle *parent_fwnode;
> +	int ret;

See Documentation about variable declarations...

> +	for (size_t i = 0; i < nc1outs; i++) {
> +		aspeed_intc_output_t c1o = c1outs[i];
> +
> +		if (c1o == AST2700_INTC_INVALID_ROUTE) {
> +			dev_dbg(intc0->dev, "%s: Invalid output at route index %zu\n",
> +				__func__, i);
> +			continue;
> +		}
> +
> +		dev_dbg(intc0->dev, "%s: Have output %u for route index %zu\n",
> +			__func__, c1o, i);
> +
> +		for (size_t j = 0; j < nc1ranges; j++) {
> +			struct aspeed_intc_interrupt_range c1r = c1ranges[j];
> +			u32 input;
> +
> +			dev_dbg(intc0->dev,
> +				"%s: Inspecting candidate range %zu starting at %u for %u\n",
> +				__func__, j, c1r.start, c1r.count);
> +
> +			/*
> +			 * Range match for intc1 output pin
> +			 *
> +			 * Assume a failed match is still a match for the purpose of testing,
> +			 * saves a bunch of mess in the test fixtures
> +			 */
> +			if (!(c0domain == irq_find_matching_fwspec(&c1r.upstream,
> +								   c0domain->bus_token) ||
> +			      IS_ENABLED(CONFIG_ASPEED_AST2700_INTC_TEST))) {
> +				dev_dbg(intc0->dev, "%s: Parent mismatch for candidate range %zu\n",
> +					__func__, j);
> +				continue;
> +			}
> +
> +			ret = resolve_input_from_child_ranges(intc0, &c1r, c1o, &input);
> +			if (ret) {
> +				if (ret == -ENOENT)
> +					dev_dbg(intc0->dev,
> +						"%s: Output %u not in candidate range %zu starting at %u for %u\n",
> +						__func__, c1o, j, c1r.start, c1r.count);
> +				continue;

All of this is unreadable and I told you about the bracket rules before, no?

> +			}
> +			dev_dbg(intc0->dev,
> +				"%s: Resolved INTC0 input to %u using candidate range %zu: [%u, %u)\n",
> +				__func__, input, j, c1r.start, c1r.start + c1r.count);
> +
> +			/*
> +			 * INTC1 should never request routes for peripheral interrupt sources
> +			 * directly attached to INTC0.
> +			 */
> +			if (input < GIC_P2P_SPI_END) {
> +				dev_dbg(intc0->dev,
> +					"%s: Invalid range specification at index %zu routed INTC1 output to unreachable INTC0 input\n",
> +					__func__, j);
> +				continue;
> +			}
> +
> +			ret = resolve_parent_route_for_input(intc0, parent_fwnode, input, NULL);
> +			if (ret < 0)
> +				continue;
> +
> +			/* Route resolution succeeded */
> +			resolved->start = c1o;
> +			resolved->count = 1;
> +			resolved->upstream = c1r.upstream;
> +			resolved->upstream.param[0] = input;
> +			dev_dbg(intc0->dev,
> +				"%s: Route resolution selected INTC1 output %u via index %zu\n",
> +				__func__, c1o, i);
> +			/* Cast protected by prior test against nc1outs */
> +			return (int)i;
> +		}
> +	}
> +
> +	ret = -EHOSTUNREACH;
> +	return ret;

Impressive.

> +}
> +EXPORT_SYMBOL_GPL(aspeed_intc0_resolve_route);

What is this export for? All usage sites are built in, no?

> +static int aspeed_intc0_irq_domain_map(struct irq_domain *domain,
> +				       unsigned int irq, irq_hw_number_t hwirq)
> +{
> +	if (hwirq < GIC_P2P_SPI_END)
> +		irq_set_chip_and_handler(irq, &linear_intr_irq_chip,
> +					 handle_level_irq);

Make this one line. Otherwise you need brackets.

> +	else if (hwirq < INTM_BASE)
> +		return -EINVAL;
> +	else if (hwirq < SWINT_BASE)
> +		irq_set_chip_and_handler(irq, &aspeed_intm_chip,
> +					 handle_level_irq);
> +	else if (hwirq < INT0_NUM)
> +		irq_set_chip_and_handler(irq, &aspeed_swint_chip,
> +					 handle_level_irq);
> +	else
> +		return -EINVAL;
> +
> +	irq_set_chip_data(irq, domain->host_data);
> +	return 0;
> +}

> +static int aspeed_intc0_irq_domain_activate(struct irq_domain *domain,
> +					    struct irq_data *data, bool reserve)
> +{
> +	struct aspeed_intc0 *intc0 = irq_data_get_irq_chip_data(data);
> +
> +	if (data->hwirq < INT_NUM) {
> +		int bank = data->hwirq / 32;
> +		int bit = data->hwirq % 32;
> +		u32 mask = BIT(bit);
> +		int route;
> +
> +		route = resolve_parent_route_for_input(intc0,
> +						       intc0->local->parent->fwnode,
> +						       data->hwirq, NULL);
> +		if (route < 0)
> +			return route;
> +
> +		guard(raw_spinlock_irqsave)(&intc0->intc_lock);
> +		for (int i = 0; i < 3; i++) {
> +			void __iomem *sel = intc0->base + 0x200 + bank * 4 + 0x100 * i;

Magic constants 0x200 4 and 0x100. Use proper defines and a macro/inline
to calculate the register address and not this incomprehensible garbage.

> +			u32 reg = readl(sel);
> +
> +			if (route & BIT(i))
> +				reg |= mask;
> +			else
> +				reg &= ~mask;
> +
> +			writel(reg, sel);
> +			if (readl(sel) != reg)
> +				return -EACCES;
> +		}
> +	} else if (data->hwirq < INT0_NUM) {
> +		return 0;
> +	} else {
> +		return -EINVAL;
> +	}

If you rearrange those conditions you can avoid the indentation all
together

        if (in_range32(data->hwirq, INTM_BASE, INTM_NUM + SWINT_NUM))
        	return 0;
        if (data->hwirq >= INT_NUM)
        	return -EINVAL;

No?

> +
> +	return 0;
> +}
> +
> +static void aspeed_intc0_disable_intbank(struct aspeed_intc0 *intc0)
> +{
> +	int i, j;
> +
> +	for (i = 0; i < INTC0_INTBANK_GROUPS; i++) {
> +		for (j = 0; j < INTC0_INTBANKS_PER_GRP; j++) {

Both i and j should be declared in the for () statement. Your coding
style is so inconsistent it's not even funny anymore. 

> +			u32 base = INTC0_INTBANKX_IER + (0x100 * i) + (0x10 * j);
> +
> +			writel(0, intc0->base + base);
> +		}
> +	}
> +}
> +IRQCHIP_PLATFORM_DRIVER_BEGIN(ast2700_intc0)
> +IRQCHIP_MATCH("aspeed,ast2700-intc0-ic", aspeed_intc0_ic_probe)
> +IRQCHIP_PLATFORM_DRIVER_END(ast2700_intc0)
> +
> +#ifdef CONFIG_ASPEED_AST2700_INTC_TEST
> +#include "irq-ast2700-intc0-test.c"
> +#endif

Yikes. What's wrong with Makefile?

> diff --git a/drivers/irqchip/irq-ast2700-intc1.c b/drivers/irqchip/irq-ast2700-intc1.c
> +static void aspeed_intc1_ic_irq_handler(struct irq_desc *desc)
> +{
> +	struct aspeed_intc1 *intc1 = irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	unsigned long bit, status;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	for (int bank = 0; bank < INTC1_BANK_NUM; bank++) {
> +		status = readl(intc1->base + INTC1_ISR + (0x10 * bank));
> +		if (!status)
> +			continue;
> +
> +		for_each_set_bit(bit, &status, INTC1_IRQS_PER_BANK) {
> +			generic_handle_domain_irq(intc1->local,
> +						  (bank * INTC1_IRQS_PER_BANK) +
> +							  bit);
> +			writel(BIT(bit),
> +			       intc1->base + INTC1_ISR + (0x10 * bank));

My eyes bleed by now.

Thanks,

        tglx
Re: [PATCH 2/4] irqchip/ast2700-intcx: Add AST2700 INTC0/INTC1 support
Posted by kernel test robot 3 days, 3 hours ago
Hi Ryan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]

url:    https://github.com/intel-lab-lkp/linux/commits/Ryan-Chen/dt-bindings-interrupt-controller-aspeed-Add-ASPEED-AST2700-INTC0-INTC1/20260205-141046
base:   8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link:    https://lore.kernel.org/r/20260205-irqchip-v1-2-b0310e06c087%40aspeedtech.com
patch subject: [PATCH 2/4] irqchip/ast2700-intcx: Add AST2700 INTC0/INTC1 support
config: mips-allyesconfig (https://download.01.org/0day-ci/archive/20260205/202602052233.HNk5pa4R-lkp@intel.com/config)
compiler: mips-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260205/202602052233.HNk5pa4R-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202602052233.HNk5pa4R-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from arch/mips/include/asm/errno.h:11,
                    from include/linux/err.h:8,
                    from include/linux/cleanup.h:6,
                    from include/linux/jump_label.h:78,
                    from include/linux/dynamic_debug.h:6,
                    from include/linux/printk.h:621,
                    from include/asm-generic/bug.h:31,
                    from arch/mips/include/asm/bug.h:42,
                    from include/linux/bug.h:5,
                    from include/linux/thread_info.h:13,
                    from include/asm-generic/current.h:6,
                    from ./arch/mips/include/generated/asm/current.h:1,
                    from include/linux/sched.h:12,
                    from include/linux/ratelimit.h:6,
                    from include/linux/dev_printk.h:16,
                    from include/linux/device.h:15,
                    from drivers/irqchip/irq-ast2700-intc0.c:10:
>> arch/mips/include/uapi/asm/errno.h:18:9: warning: 'ENOMSG' redefined
      18 | #define ENOMSG          35      /* No message of desired type */
         |         ^~~~~~
   In file included from drivers/irqchip/irq-ast2700-intc0.c:8:
   include/uapi/asm-generic/errno.h:23:9: note: this is the location of the previous definition
      23 | #define ENOMSG          42      /* No message of desired type */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:19:9: warning: 'EIDRM' redefined
      19 | #define EIDRM           36      /* Identifier removed */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:24:9: note: this is the location of the previous definition
      24 | #define EIDRM           43      /* Identifier removed */
         |         ^~~~~
>> arch/mips/include/uapi/asm/errno.h:20:9: warning: 'ECHRNG' redefined
      20 | #define ECHRNG          37      /* Channel number out of range */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:25:9: note: this is the location of the previous definition
      25 | #define ECHRNG          44      /* Channel number out of range */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:21:9: warning: 'EL2NSYNC' redefined
      21 | #define EL2NSYNC        38      /* Level 2 not synchronized */
         |         ^~~~~~~~
   include/uapi/asm-generic/errno.h:26:9: note: this is the location of the previous definition
      26 | #define EL2NSYNC        45      /* Level 2 not synchronized */
         |         ^~~~~~~~
>> arch/mips/include/uapi/asm/errno.h:22:9: warning: 'EL3HLT' redefined
      22 | #define EL3HLT          39      /* Level 3 halted */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:27:9: note: this is the location of the previous definition
      27 | #define EL3HLT          46      /* Level 3 halted */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:23:9: warning: 'EL3RST' redefined
      23 | #define EL3RST          40      /* Level 3 reset */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:28:9: note: this is the location of the previous definition
      28 | #define EL3RST          47      /* Level 3 reset */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:24:9: warning: 'ELNRNG' redefined
      24 | #define ELNRNG          41      /* Link number out of range */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:29:9: note: this is the location of the previous definition
      29 | #define ELNRNG          48      /* Link number out of range */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:25:9: warning: 'EUNATCH' redefined
      25 | #define EUNATCH         42      /* Protocol driver not attached */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:30:9: note: this is the location of the previous definition
      30 | #define EUNATCH         49      /* Protocol driver not attached */
         |         ^~~~~~~
>> arch/mips/include/uapi/asm/errno.h:26:9: warning: 'ENOCSI' redefined
      26 | #define ENOCSI          43      /* No CSI structure available */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:31:9: note: this is the location of the previous definition
      31 | #define ENOCSI          50      /* No CSI structure available */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:27:9: warning: 'EL2HLT' redefined
      27 | #define EL2HLT          44      /* Level 2 halted */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:32:9: note: this is the location of the previous definition
      32 | #define EL2HLT          51      /* Level 2 halted */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:28:9: warning: 'EDEADLK' redefined
      28 | #define EDEADLK         45      /* Resource deadlock would occur */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:7:9: note: this is the location of the previous definition
       7 | #define EDEADLK         35      /* Resource deadlock would occur */
         |         ^~~~~~~
>> arch/mips/include/uapi/asm/errno.h:29:9: warning: 'ENOLCK' redefined
      29 | #define ENOLCK          46      /* No record locks available */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:9:9: note: this is the location of the previous definition
       9 | #define ENOLCK          37      /* No record locks available */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:30:9: warning: 'EBADE' redefined
      30 | #define EBADE           50      /* Invalid exchange */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:33:9: note: this is the location of the previous definition
      33 | #define EBADE           52      /* Invalid exchange */
         |         ^~~~~
>> arch/mips/include/uapi/asm/errno.h:31:9: warning: 'EBADR' redefined
      31 | #define EBADR           51      /* Invalid request descriptor */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:34:9: note: this is the location of the previous definition
      34 | #define EBADR           53      /* Invalid request descriptor */
         |         ^~~~~
>> arch/mips/include/uapi/asm/errno.h:32:9: warning: 'EXFULL' redefined
      32 | #define EXFULL          52      /* Exchange full */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:35:9: note: this is the location of the previous definition
      35 | #define EXFULL          54      /* Exchange full */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:33:9: warning: 'ENOANO' redefined
      33 | #define ENOANO          53      /* No anode */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:36:9: note: this is the location of the previous definition
      36 | #define ENOANO          55      /* No anode */
         |         ^~~~~~
>> arch/mips/include/uapi/asm/errno.h:34:9: warning: 'EBADRQC' redefined
      34 | #define EBADRQC         54      /* Invalid request code */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:37:9: note: this is the location of the previous definition
      37 | #define EBADRQC         56      /* Invalid request code */
         |         ^~~~~~~
>> arch/mips/include/uapi/asm/errno.h:35:9: warning: 'EBADSLT' redefined
      35 | #define EBADSLT         55      /* Invalid slot */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:38:9: note: this is the location of the previous definition
      38 | #define EBADSLT         57      /* Invalid slot */
         |         ^~~~~~~
>> arch/mips/include/uapi/asm/errno.h:36:9: warning: 'EDEADLOCK' redefined
      36 | #define EDEADLOCK       56      /* File locking deadlock error */
         |         ^~~~~~~~~
   include/uapi/asm-generic/errno.h:40:9: note: this is the location of the previous definition
      40 | #define EDEADLOCK       EDEADLK
         |         ^~~~~~~~~
>> arch/mips/include/uapi/asm/errno.h:51:9: warning: 'EMULTIHOP' redefined
      51 | #define EMULTIHOP       74      /* Multihop attempted */
         |         ^~~~~~~~~
   include/uapi/asm-generic/errno.h:55:9: note: this is the location of the previous definition
      55 | #define EMULTIHOP       72      /* Multihop attempted */
         |         ^~~~~~~~~
   arch/mips/include/uapi/asm/errno.h:52:9: warning: 'EBADMSG' redefined
      52 | #define EBADMSG         77      /* Not a data message */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:57:9: note: this is the location of the previous definition
      57 | #define EBADMSG         74      /* Not a data message */
         |         ^~~~~~~
   arch/mips/include/uapi/asm/errno.h:53:9: warning: 'ENAMETOOLONG' redefined
      53 | #define ENAMETOOLONG    78      /* File name too long */
         |         ^~~~~~~~~~~~
   include/uapi/asm-generic/errno.h:8:9: note: this is the location of the previous definition
       8 | #define ENAMETOOLONG    36      /* File name too long */
         |         ^~~~~~~~~~~~
   arch/mips/include/uapi/asm/errno.h:54:9: warning: 'EOVERFLOW' redefined
      54 | #define EOVERFLOW       79      /* Value too large for defined data type */
         |         ^~~~~~~~~
   include/uapi/asm-generic/errno.h:58:9: note: this is the location of the previous definition
      58 | #define EOVERFLOW       75      /* Value too large for defined data type */
         |         ^~~~~~~~~
   arch/mips/include/uapi/asm/errno.h:55:9: warning: 'ENOTUNIQ' redefined
      55 | #define ENOTUNIQ        80      /* Name not unique on network */
         |         ^~~~~~~~
   include/uapi/asm-generic/errno.h:59:9: note: this is the location of the previous definition
      59 | #define ENOTUNIQ        76      /* Name not unique on network */
         |         ^~~~~~~~
   arch/mips/include/uapi/asm/errno.h:56:9: warning: 'EBADFD' redefined
      56 | #define EBADFD          81      /* File descriptor in bad state */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:60:9: note: this is the location of the previous definition
      60 | #define EBADFD          77      /* File descriptor in bad state */
         |         ^~~~~~
   arch/mips/include/uapi/asm/errno.h:57:9: warning: 'EREMCHG' redefined
      57 | #define EREMCHG         82      /* Remote address changed */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:61:9: note: this is the location of the previous definition
      61 | #define EREMCHG         78      /* Remote address changed */
         |         ^~~~~~~
   arch/mips/include/uapi/asm/errno.h:58:9: warning: 'ELIBACC' redefined
      58 | #define ELIBACC         83      /* Can not access a needed shared library */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:62:9: note: this is the location of the previous definition
      62 | #define ELIBACC         79      /* Can not access a needed shared library */
         |         ^~~~~~~
   arch/mips/include/uapi/asm/errno.h:59:9: warning: 'ELIBBAD' redefined
      59 | #define ELIBBAD         84      /* Accessing a corrupted shared library */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:63:9: note: this is the location of the previous definition
      63 | #define ELIBBAD         80      /* Accessing a corrupted shared library */
         |         ^~~~~~~
   arch/mips/include/uapi/asm/errno.h:60:9: warning: 'ELIBSCN' redefined
      60 | #define ELIBSCN         85      /* .lib section in a.out corrupted */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:64:9: note: this is the location of the previous definition
      64 | #define ELIBSCN         81      /* .lib section in a.out corrupted */
         |         ^~~~~~~
   arch/mips/include/uapi/asm/errno.h:61:9: warning: 'ELIBMAX' redefined
      61 | #define ELIBMAX         86      /* Attempting to link in too many shared libraries */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:65:9: note: this is the location of the previous definition
      65 | #define ELIBMAX         82      /* Attempting to link in too many shared libraries */
         |         ^~~~~~~
   arch/mips/include/uapi/asm/errno.h:62:9: warning: 'ELIBEXEC' redefined
      62 | #define ELIBEXEC        87      /* Cannot exec a shared library directly */
         |         ^~~~~~~~
   include/uapi/asm-generic/errno.h:66:9: note: this is the location of the previous definition
      66 | #define ELIBEXEC        83      /* Cannot exec a shared library directly */
         |         ^~~~~~~~
   arch/mips/include/uapi/asm/errno.h:63:9: warning: 'EILSEQ' redefined
      63 | #define EILSEQ          88      /* Illegal byte sequence */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:67:9: note: this is the location of the previous definition
      67 | #define EILSEQ          84      /* Illegal byte sequence */
         |         ^~~~~~
   arch/mips/include/uapi/asm/errno.h:64:9: warning: 'ENOSYS' redefined
      64 | #define ENOSYS          89      /* Function not implemented */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:18:9: note: this is the location of the previous definition
      18 | #define ENOSYS          38      /* Invalid system call number */
         |         ^~~~~~
   arch/mips/include/uapi/asm/errno.h:65:9: warning: 'ELOOP' redefined
      65 | #define ELOOP           90      /* Too many symbolic links encountered */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:21:9: note: this is the location of the previous definition
      21 | #define ELOOP           40      /* Too many symbolic links encountered */
         |         ^~~~~
   arch/mips/include/uapi/asm/errno.h:66:9: warning: 'ERESTART' redefined
      66 | #define ERESTART        91      /* Interrupted system call should be restarted */
         |         ^~~~~~~~
   include/uapi/asm-generic/errno.h:68:9: note: this is the location of the previous definition
      68 | #define ERESTART        85      /* Interrupted system call should be restarted */
         |         ^~~~~~~~
   arch/mips/include/uapi/asm/errno.h:67:9: warning: 'ESTRPIPE' redefined
      67 | #define ESTRPIPE        92      /* Streams pipe error */
         |         ^~~~~~~~
   include/uapi/asm-generic/errno.h:69:9: note: this is the location of the previous definition
      69 | #define ESTRPIPE        86      /* Streams pipe error */


vim +/ENOMSG +18 arch/mips/include/uapi/asm/errno.h

61730c538f8281 David Howells 2012-10-09   17  
61730c538f8281 David Howells 2012-10-09  @18  #define ENOMSG		35	/* No message of desired type */
61730c538f8281 David Howells 2012-10-09  @19  #define EIDRM		36	/* Identifier removed */
61730c538f8281 David Howells 2012-10-09  @20  #define ECHRNG		37	/* Channel number out of range */
61730c538f8281 David Howells 2012-10-09  @21  #define EL2NSYNC	38	/* Level 2 not synchronized */
61730c538f8281 David Howells 2012-10-09  @22  #define EL3HLT		39	/* Level 3 halted */
61730c538f8281 David Howells 2012-10-09  @23  #define EL3RST		40	/* Level 3 reset */
61730c538f8281 David Howells 2012-10-09  @24  #define ELNRNG		41	/* Link number out of range */
61730c538f8281 David Howells 2012-10-09  @25  #define EUNATCH		42	/* Protocol driver not attached */
61730c538f8281 David Howells 2012-10-09  @26  #define ENOCSI		43	/* No CSI structure available */
61730c538f8281 David Howells 2012-10-09  @27  #define EL2HLT		44	/* Level 2 halted */
61730c538f8281 David Howells 2012-10-09  @28  #define EDEADLK		45	/* Resource deadlock would occur */
61730c538f8281 David Howells 2012-10-09  @29  #define ENOLCK		46	/* No record locks available */
61730c538f8281 David Howells 2012-10-09  @30  #define EBADE		50	/* Invalid exchange */
61730c538f8281 David Howells 2012-10-09  @31  #define EBADR		51	/* Invalid request descriptor */
61730c538f8281 David Howells 2012-10-09  @32  #define EXFULL		52	/* Exchange full */
61730c538f8281 David Howells 2012-10-09  @33  #define ENOANO		53	/* No anode */
61730c538f8281 David Howells 2012-10-09  @34  #define EBADRQC		54	/* Invalid request code */
61730c538f8281 David Howells 2012-10-09  @35  #define EBADSLT		55	/* Invalid slot */
61730c538f8281 David Howells 2012-10-09  @36  #define EDEADLOCK	56	/* File locking deadlock error */
61730c538f8281 David Howells 2012-10-09   37  #define EBFONT		59	/* Bad font file format */
61730c538f8281 David Howells 2012-10-09   38  #define ENOSTR		60	/* Device not a stream */
61730c538f8281 David Howells 2012-10-09   39  #define ENODATA		61	/* No data available */
61730c538f8281 David Howells 2012-10-09   40  #define ETIME		62	/* Timer expired */
61730c538f8281 David Howells 2012-10-09   41  #define ENOSR		63	/* Out of streams resources */
61730c538f8281 David Howells 2012-10-09   42  #define ENONET		64	/* Machine is not on the network */
61730c538f8281 David Howells 2012-10-09   43  #define ENOPKG		65	/* Package not installed */
61730c538f8281 David Howells 2012-10-09   44  #define EREMOTE		66	/* Object is remote */
61730c538f8281 David Howells 2012-10-09   45  #define ENOLINK		67	/* Link has been severed */
61730c538f8281 David Howells 2012-10-09   46  #define EADV		68	/* Advertise error */
61730c538f8281 David Howells 2012-10-09   47  #define ESRMNT		69	/* Srmount error */
61730c538f8281 David Howells 2012-10-09   48  #define ECOMM		70	/* Communication error on send */
61730c538f8281 David Howells 2012-10-09   49  #define EPROTO		71	/* Protocol error */
61730c538f8281 David Howells 2012-10-09   50  #define EDOTDOT		73	/* RFS specific error */
61730c538f8281 David Howells 2012-10-09  @51  #define EMULTIHOP	74	/* Multihop attempted */
61730c538f8281 David Howells 2012-10-09  @52  #define EBADMSG		77	/* Not a data message */
61730c538f8281 David Howells 2012-10-09  @53  #define ENAMETOOLONG	78	/* File name too long */
61730c538f8281 David Howells 2012-10-09  @54  #define EOVERFLOW	79	/* Value too large for defined data type */
61730c538f8281 David Howells 2012-10-09  @55  #define ENOTUNIQ	80	/* Name not unique on network */
61730c538f8281 David Howells 2012-10-09  @56  #define EBADFD		81	/* File descriptor in bad state */
61730c538f8281 David Howells 2012-10-09  @57  #define EREMCHG		82	/* Remote address changed */
61730c538f8281 David Howells 2012-10-09  @58  #define ELIBACC		83	/* Can not access a needed shared library */
61730c538f8281 David Howells 2012-10-09  @59  #define ELIBBAD		84	/* Accessing a corrupted shared library */
61730c538f8281 David Howells 2012-10-09  @60  #define ELIBSCN		85	/* .lib section in a.out corrupted */
61730c538f8281 David Howells 2012-10-09  @61  #define ELIBMAX		86	/* Attempting to link in too many shared libraries */
61730c538f8281 David Howells 2012-10-09  @62  #define ELIBEXEC	87	/* Cannot exec a shared library directly */
61730c538f8281 David Howells 2012-10-09  @63  #define EILSEQ		88	/* Illegal byte sequence */
61730c538f8281 David Howells 2012-10-09  @64  #define ENOSYS		89	/* Function not implemented */
61730c538f8281 David Howells 2012-10-09  @65  #define ELOOP		90	/* Too many symbolic links encountered */
61730c538f8281 David Howells 2012-10-09  @66  #define ERESTART	91	/* Interrupted system call should be restarted */
61730c538f8281 David Howells 2012-10-09  @67  #define ESTRPIPE	92	/* Streams pipe error */
61730c538f8281 David Howells 2012-10-09  @68  #define ENOTEMPTY	93	/* Directory not empty */
61730c538f8281 David Howells 2012-10-09  @69  #define EUSERS		94	/* Too many users */
61730c538f8281 David Howells 2012-10-09  @70  #define ENOTSOCK	95	/* Socket operation on non-socket */
61730c538f8281 David Howells 2012-10-09  @71  #define EDESTADDRREQ	96	/* Destination address required */
61730c538f8281 David Howells 2012-10-09  @72  #define EMSGSIZE	97	/* Message too long */
61730c538f8281 David Howells 2012-10-09  @73  #define EPROTOTYPE	98	/* Protocol wrong type for socket */
61730c538f8281 David Howells 2012-10-09  @74  #define ENOPROTOOPT	99	/* Protocol not available */
61730c538f8281 David Howells 2012-10-09  @75  #define EPROTONOSUPPORT 120	/* Protocol not supported */
61730c538f8281 David Howells 2012-10-09  @76  #define ESOCKTNOSUPPORT 121	/* Socket type not supported */
61730c538f8281 David Howells 2012-10-09  @77  #define EOPNOTSUPP	122	/* Operation not supported on transport endpoint */
61730c538f8281 David Howells 2012-10-09  @78  #define EPFNOSUPPORT	123	/* Protocol family not supported */
61730c538f8281 David Howells 2012-10-09  @79  #define EAFNOSUPPORT	124	/* Address family not supported by protocol */
61730c538f8281 David Howells 2012-10-09  @80  #define EADDRINUSE	125	/* Address already in use */
61730c538f8281 David Howells 2012-10-09  @81  #define EADDRNOTAVAIL	126	/* Cannot assign requested address */
61730c538f8281 David Howells 2012-10-09  @82  #define ENETDOWN	127	/* Network is down */
61730c538f8281 David Howells 2012-10-09  @83  #define ENETUNREACH	128	/* Network is unreachable */
61730c538f8281 David Howells 2012-10-09  @84  #define ENETRESET	129	/* Network dropped connection because of reset */
61730c538f8281 David Howells 2012-10-09  @85  #define ECONNABORTED	130	/* Software caused connection abort */
61730c538f8281 David Howells 2012-10-09  @86  #define ECONNRESET	131	/* Connection reset by peer */
61730c538f8281 David Howells 2012-10-09  @87  #define ENOBUFS		132	/* No buffer space available */
61730c538f8281 David Howells 2012-10-09  @88  #define EISCONN		133	/* Transport endpoint is already connected */
61730c538f8281 David Howells 2012-10-09  @89  #define ENOTCONN	134	/* Transport endpoint is not connected */
61730c538f8281 David Howells 2012-10-09  @90  #define EUCLEAN		135	/* Structure needs cleaning */
61730c538f8281 David Howells 2012-10-09  @91  #define ENOTNAM		137	/* Not a XENIX named type file */
61730c538f8281 David Howells 2012-10-09  @92  #define ENAVAIL		138	/* No XENIX semaphores available */
61730c538f8281 David Howells 2012-10-09  @93  #define EISNAM		139	/* Is a named type file */
61730c538f8281 David Howells 2012-10-09  @94  #define EREMOTEIO	140	/* Remote I/O error */
61730c538f8281 David Howells 2012-10-09   95  #define EINIT		141	/* Reserved */
61730c538f8281 David Howells 2012-10-09   96  #define EREMDEV		142	/* Error 142 */
61730c538f8281 David Howells 2012-10-09  @97  #define ESHUTDOWN	143	/* Cannot send after transport endpoint shutdown */
61730c538f8281 David Howells 2012-10-09  @98  #define ETOOMANYREFS	144	/* Too many references: cannot splice */
61730c538f8281 David Howells 2012-10-09  @99  #define ETIMEDOUT	145	/* Connection timed out */
61730c538f8281 David Howells 2012-10-09 @100  #define ECONNREFUSED	146	/* Connection refused */
61730c538f8281 David Howells 2012-10-09 @101  #define EHOSTDOWN	147	/* Host is down */
61730c538f8281 David Howells 2012-10-09 @102  #define EHOSTUNREACH	148	/* No route to host */
61730c538f8281 David Howells 2012-10-09  103  #define EWOULDBLOCK	EAGAIN	/* Operation would block */
61730c538f8281 David Howells 2012-10-09 @104  #define EALREADY	149	/* Operation already in progress */
61730c538f8281 David Howells 2012-10-09 @105  #define EINPROGRESS	150	/* Operation now in progress */
0ca43435188b9f Eric Sandeen  2013-11-12 @106  #define ESTALE		151	/* Stale file handle */
61730c538f8281 David Howells 2012-10-09 @107  #define ECANCELED	158	/* AIO operation canceled */
61730c538f8281 David Howells 2012-10-09  108  
61730c538f8281 David Howells 2012-10-09  109  /*
61730c538f8281 David Howells 2012-10-09  110   * These error are Linux extensions.
61730c538f8281 David Howells 2012-10-09  111   */
61730c538f8281 David Howells 2012-10-09 @112  #define ENOMEDIUM	159	/* No medium found */
61730c538f8281 David Howells 2012-10-09 @113  #define EMEDIUMTYPE	160	/* Wrong medium type */
61730c538f8281 David Howells 2012-10-09 @114  #define ENOKEY		161	/* Required key not available */
61730c538f8281 David Howells 2012-10-09 @115  #define EKEYEXPIRED	162	/* Key has expired */
61730c538f8281 David Howells 2012-10-09 @116  #define EKEYREVOKED	163	/* Key has been revoked */
61730c538f8281 David Howells 2012-10-09 @117  #define EKEYREJECTED	164	/* Key was rejected by service */
61730c538f8281 David Howells 2012-10-09  118  
61730c538f8281 David Howells 2012-10-09  119  /* for robust mutexes */
61730c538f8281 David Howells 2012-10-09 @120  #define EOWNERDEAD	165	/* Owner died */
61730c538f8281 David Howells 2012-10-09 @121  #define ENOTRECOVERABLE 166	/* State not recoverable */
61730c538f8281 David Howells 2012-10-09  122  
61730c538f8281 David Howells 2012-10-09 @123  #define ERFKILL		167	/* Operation not possible due to RF-kill */
61730c538f8281 David Howells 2012-10-09  124  
61730c538f8281 David Howells 2012-10-09 @125  #define EHWPOISON	168	/* Memory page has hardware error */
61730c538f8281 David Howells 2012-10-09  126  
61730c538f8281 David Howells 2012-10-09 @127  #define EDQUOT		1133	/* Quota exceeded */
61730c538f8281 David Howells 2012-10-09  128  
61730c538f8281 David Howells 2012-10-09  129  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH 2/4] irqchip/ast2700-intcx: Add AST2700 INTC0/INTC1 support
Posted by kernel test robot 3 days, 3 hours ago
Hi Ryan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 8f0b4cce4481fb22653697cced8d0d04027cb1e8]

url:    https://github.com/intel-lab-lkp/linux/commits/Ryan-Chen/dt-bindings-interrupt-controller-aspeed-Add-ASPEED-AST2700-INTC0-INTC1/20260205-141046
base:   8f0b4cce4481fb22653697cced8d0d04027cb1e8
patch link:    https://lore.kernel.org/r/20260205-irqchip-v1-2-b0310e06c087%40aspeedtech.com
patch subject: [PATCH 2/4] irqchip/ast2700-intcx: Add AST2700 INTC0/INTC1 support
config: parisc-allyesconfig (https://download.01.org/0day-ci/archive/20260205/202602052259.vW8lLakZ-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 15.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260205/202602052259.vW8lLakZ-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202602052259.vW8lLakZ-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from include/linux/err.h:8,
                    from include/linux/cleanup.h:6,
                    from include/linux/irqflags.h:17,
                    from include/asm-generic/cmpxchg-local.h:6,
                    from arch/parisc/include/asm/cmpxchg.h:87,
                    from arch/parisc/include/asm/atomic.h:10,
                    from include/linux/atomic.h:7,
                    from arch/parisc/include/asm/bitops.h:13,
                    from include/linux/bitops.h:67,
                    from drivers/irqchip/irq-ast2700-intc0.c:9:
>> arch/parisc/include/uapi/asm/errno.h:7:9: warning: 'ENOMSG' redefined
       7 | #define ENOMSG          35      /* No message of desired type */
         |         ^~~~~~
   In file included from drivers/irqchip/irq-ast2700-intc0.c:8:
   include/uapi/asm-generic/errno.h:23:9: note: this is the location of the previous definition
      23 | #define ENOMSG          42      /* No message of desired type */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:8:9: warning: 'EIDRM' redefined
       8 | #define EIDRM           36      /* Identifier removed */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:24:9: note: this is the location of the previous definition
      24 | #define EIDRM           43      /* Identifier removed */
         |         ^~~~~
>> arch/parisc/include/uapi/asm/errno.h:9:9: warning: 'ECHRNG' redefined
       9 | #define ECHRNG          37      /* Channel number out of range */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:25:9: note: this is the location of the previous definition
      25 | #define ECHRNG          44      /* Channel number out of range */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:10:9: warning: 'EL2NSYNC' redefined
      10 | #define EL2NSYNC        38      /* Level 2 not synchronized */
         |         ^~~~~~~~
   include/uapi/asm-generic/errno.h:26:9: note: this is the location of the previous definition
      26 | #define EL2NSYNC        45      /* Level 2 not synchronized */
         |         ^~~~~~~~
>> arch/parisc/include/uapi/asm/errno.h:11:9: warning: 'EL3HLT' redefined
      11 | #define EL3HLT          39      /* Level 3 halted */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:27:9: note: this is the location of the previous definition
      27 | #define EL3HLT          46      /* Level 3 halted */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:12:9: warning: 'EL3RST' redefined
      12 | #define EL3RST          40      /* Level 3 reset */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:28:9: note: this is the location of the previous definition
      28 | #define EL3RST          47      /* Level 3 reset */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:13:9: warning: 'ELNRNG' redefined
      13 | #define ELNRNG          41      /* Link number out of range */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:29:9: note: this is the location of the previous definition
      29 | #define ELNRNG          48      /* Link number out of range */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:14:9: warning: 'EUNATCH' redefined
      14 | #define EUNATCH         42      /* Protocol driver not attached */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:30:9: note: this is the location of the previous definition
      30 | #define EUNATCH         49      /* Protocol driver not attached */
         |         ^~~~~~~
>> arch/parisc/include/uapi/asm/errno.h:15:9: warning: 'ENOCSI' redefined
      15 | #define ENOCSI          43      /* No CSI structure available */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:31:9: note: this is the location of the previous definition
      31 | #define ENOCSI          50      /* No CSI structure available */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:16:9: warning: 'EL2HLT' redefined
      16 | #define EL2HLT          44      /* Level 2 halted */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:32:9: note: this is the location of the previous definition
      32 | #define EL2HLT          51      /* Level 2 halted */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:17:9: warning: 'EDEADLK' redefined
      17 | #define EDEADLK         45      /* Resource deadlock would occur */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:7:9: note: this is the location of the previous definition
       7 | #define EDEADLK         35      /* Resource deadlock would occur */
         |         ^~~~~~~
>> arch/parisc/include/uapi/asm/errno.h:19:9: warning: 'ENOLCK' redefined
      19 | #define ENOLCK          46      /* No record locks available */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:9:9: note: this is the location of the previous definition
       9 | #define ENOLCK          37      /* No record locks available */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:20:9: warning: 'EILSEQ' redefined
      20 | #define EILSEQ          47      /* Illegal byte sequence */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:67:9: note: this is the location of the previous definition
      67 | #define EILSEQ          84      /* Illegal byte sequence */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:22:9: warning: 'ENONET' redefined
      22 | #define ENONET          50      /* Machine is not on the network */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:47:9: note: this is the location of the previous definition
      47 | #define ENONET          64      /* Machine is not on the network */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:23:9: warning: 'ENODATA' redefined
      23 | #define ENODATA         51      /* No data available */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:44:9: note: this is the location of the previous definition
      44 | #define ENODATA         61      /* No data available */
         |         ^~~~~~~
>> arch/parisc/include/uapi/asm/errno.h:24:9: warning: 'ETIME' redefined
      24 | #define ETIME           52      /* Timer expired */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:45:9: note: this is the location of the previous definition
      45 | #define ETIME           62      /* Timer expired */
         |         ^~~~~
>> arch/parisc/include/uapi/asm/errno.h:25:9: warning: 'ENOSR' redefined
      25 | #define ENOSR           53      /* Out of streams resources */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:46:9: note: this is the location of the previous definition
      46 | #define ENOSR           63      /* Out of streams resources */
         |         ^~~~~
>> arch/parisc/include/uapi/asm/errno.h:26:9: warning: 'ENOSTR' redefined
      26 | #define ENOSTR          54      /* Device not a stream */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:43:9: note: this is the location of the previous definition
      43 | #define ENOSTR          60      /* Device not a stream */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:27:9: warning: 'ENOPKG' redefined
      27 | #define ENOPKG          55      /* Package not installed */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:48:9: note: this is the location of the previous definition
      48 | #define ENOPKG          65      /* Package not installed */
         |         ^~~~~~
>> arch/parisc/include/uapi/asm/errno.h:29:9: warning: 'ENOLINK' redefined
      29 | #define ENOLINK         57      /* Link has been severed */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:50:9: note: this is the location of the previous definition
      50 | #define ENOLINK         67      /* Link has been severed */
         |         ^~~~~~~
   arch/parisc/include/uapi/asm/errno.h:30:9: warning: 'EADV' redefined
      30 | #define EADV            58      /* Advertise error */
         |         ^~~~
   include/uapi/asm-generic/errno.h:51:9: note: this is the location of the previous definition
      51 | #define EADV            68      /* Advertise error */
         |         ^~~~
   arch/parisc/include/uapi/asm/errno.h:31:9: warning: 'ESRMNT' redefined
      31 | #define ESRMNT          59      /* Srmount error */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:52:9: note: this is the location of the previous definition
      52 | #define ESRMNT          69      /* Srmount error */
         |         ^~~~~~
   arch/parisc/include/uapi/asm/errno.h:32:9: warning: 'ECOMM' redefined
      32 | #define ECOMM           60      /* Communication error on send */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:53:9: note: this is the location of the previous definition
      53 | #define ECOMM           70      /* Communication error on send */
         |         ^~~~~
   arch/parisc/include/uapi/asm/errno.h:33:9: warning: 'EPROTO' redefined
      33 | #define EPROTO          61      /* Protocol error */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:54:9: note: this is the location of the previous definition
      54 | #define EPROTO          71      /* Protocol error */
         |         ^~~~~~
   arch/parisc/include/uapi/asm/errno.h:35:9: warning: 'EMULTIHOP' redefined
      35 | #define EMULTIHOP       64      /* Multihop attempted */
         |         ^~~~~~~~~
   include/uapi/asm-generic/errno.h:55:9: note: this is the location of the previous definition
      55 | #define EMULTIHOP       72      /* Multihop attempted */
         |         ^~~~~~~~~
   arch/parisc/include/uapi/asm/errno.h:37:9: warning: 'EDOTDOT' redefined
      37 | #define EDOTDOT         66      /* RFS specific error */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:56:9: note: this is the location of the previous definition
      56 | #define EDOTDOT         73      /* RFS specific error */
         |         ^~~~~~~
   arch/parisc/include/uapi/asm/errno.h:38:9: warning: 'EBADMSG' redefined
      38 | #define EBADMSG         67      /* Not a data message */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:57:9: note: this is the location of the previous definition
      57 | #define EBADMSG         74      /* Not a data message */
         |         ^~~~~~~
   arch/parisc/include/uapi/asm/errno.h:39:9: warning: 'EUSERS' redefined
      39 | #define EUSERS          68      /* Too many users */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:70:9: note: this is the location of the previous definition
      70 | #define EUSERS          87      /* Too many users */
         |         ^~~~~~
   arch/parisc/include/uapi/asm/errno.h:40:9: warning: 'EDQUOT' redefined
      40 | #define EDQUOT          69      /* Quota exceeded */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:105:9: note: this is the location of the previous definition
     105 | #define EDQUOT          122     /* Quota exceeded */
         |         ^~~~~~
   arch/parisc/include/uapi/asm/errno.h:41:9: warning: 'ESTALE' redefined
      41 | #define ESTALE          70      /* Stale file handle */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:99:9: note: this is the location of the previous definition
      99 | #define ESTALE          116     /* Stale file handle */
         |         ^~~~~~
   arch/parisc/include/uapi/asm/errno.h:42:9: warning: 'EREMOTE' redefined
      42 | #define EREMOTE         71      /* Object is remote */
         |         ^~~~~~~
   include/uapi/asm-generic/errno.h:49:9: note: this is the location of the previous definition
      49 | #define EREMOTE         66      /* Object is remote */
         |         ^~~~~~~
   arch/parisc/include/uapi/asm/errno.h:43:9: warning: 'EOVERFLOW' redefined
      43 | #define EOVERFLOW       72      /* Value too large for defined data type */
         |         ^~~~~~~~~
   include/uapi/asm-generic/errno.h:58:9: note: this is the location of the previous definition
      58 | #define EOVERFLOW       75      /* Value too large for defined data type */
         |         ^~~~~~~~~
   arch/parisc/include/uapi/asm/errno.h:47:9: warning: 'EBADE' redefined
      47 | #define EBADE           160     /* Invalid exchange */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:33:9: note: this is the location of the previous definition
      33 | #define EBADE           52      /* Invalid exchange */
         |         ^~~~~
   arch/parisc/include/uapi/asm/errno.h:48:9: warning: 'EBADR' redefined
      48 | #define EBADR           161     /* Invalid request descriptor */
         |         ^~~~~
   include/uapi/asm-generic/errno.h:34:9: note: this is the location of the previous definition
      34 | #define EBADR           53      /* Invalid request descriptor */
         |         ^~~~~
   arch/parisc/include/uapi/asm/errno.h:49:9: warning: 'EXFULL' redefined
      49 | #define EXFULL          162     /* Exchange full */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:35:9: note: this is the location of the previous definition
      35 | #define EXFULL          54      /* Exchange full */
         |         ^~~~~~
   arch/parisc/include/uapi/asm/errno.h:50:9: warning: 'ENOANO' redefined
      50 | #define ENOANO          163     /* No anode */
         |         ^~~~~~
   include/uapi/asm-generic/errno.h:36:9: note: this is the location of the previous definition
      36 | #define ENOANO          55      /* No anode */


vim +/ENOMSG +7 arch/parisc/include/uapi/asm/errno.h

^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16    6  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   @7  #define	ENOMSG		35	/* No message of desired type */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   @8  #define	EIDRM		36	/* Identifier removed */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   @9  #define	ECHRNG		37	/* Channel number out of range */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @10  #define	EL2NSYNC	38	/* Level 2 not synchronized */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @11  #define	EL3HLT		39	/* Level 3 halted */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @12  #define	EL3RST		40	/* Level 3 reset */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @13  #define	ELNRNG		41	/* Link number out of range */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @14  #define	EUNATCH		42	/* Protocol driver not attached */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @15  #define	ENOCSI		43	/* No CSI structure available */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @16  #define	EL2HLT		44	/* Level 2 halted */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @17  #define	EDEADLK		45	/* Resource deadlock would occur */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   18  #define	EDEADLOCK	EDEADLK
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @19  #define	ENOLCK		46	/* No record locks available */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @20  #define	EILSEQ		47	/* Illegal byte sequence */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   21  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @22  #define	ENONET		50	/* Machine is not on the network */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @23  #define	ENODATA		51	/* No data available */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @24  #define	ETIME		52	/* Timer expired */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @25  #define	ENOSR		53	/* Out of streams resources */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @26  #define	ENOSTR		54	/* Device not a stream */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @27  #define	ENOPKG		55	/* Package not installed */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   28  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @29  #define	ENOLINK		57	/* Link has been severed */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @30  #define	EADV		58	/* Advertise error */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @31  #define	ESRMNT		59	/* Srmount error */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @32  #define	ECOMM		60	/* Communication error on send */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @33  #define	EPROTO		61	/* Protocol error */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   34  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @35  #define	EMULTIHOP	64	/* Multihop attempted */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   36  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @37  #define	EDOTDOT		66	/* RFS specific error */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @38  #define	EBADMSG		67	/* Not a data message */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @39  #define	EUSERS		68	/* Too many users */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @40  #define	EDQUOT		69	/* Quota exceeded */
0ca43435188b9f9 arch/parisc/include/uapi/asm/errno.h Eric Sandeen        2013-11-12  @41  #define	ESTALE		70	/* Stale file handle */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @42  #define	EREMOTE		71	/* Object is remote */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @43  #define	EOVERFLOW	72	/* Value too large for defined data type */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   44  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   45  /* these errnos are defined by Linux but not HPUX. */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   46  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @47  #define	EBADE		160	/* Invalid exchange */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @48  #define	EBADR		161	/* Invalid request descriptor */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @49  #define	EXFULL		162	/* Exchange full */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @50  #define	ENOANO		163	/* No anode */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @51  #define	EBADRQC		164	/* Invalid request code */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @52  #define	EBADSLT		165	/* Invalid slot */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @53  #define	EBFONT		166	/* Bad font file format */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @54  #define	ENOTUNIQ	167	/* Name not unique on network */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @55  #define	EBADFD		168	/* File descriptor in bad state */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @56  #define	EREMCHG		169	/* Remote address changed */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @57  #define	ELIBACC		170	/* Can not access a needed shared library */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @58  #define	ELIBBAD		171	/* Accessing a corrupted shared library */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @59  #define	ELIBSCN		172	/* .lib section in a.out corrupted */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @60  #define	ELIBMAX		173	/* Attempting to link in too many shared libraries */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @61  #define	ELIBEXEC	174	/* Cannot exec a shared library directly */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @62  #define	ERESTART	175	/* Interrupted system call should be restarted */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @63  #define	ESTRPIPE	176	/* Streams pipe error */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @64  #define	EUCLEAN		177	/* Structure needs cleaning */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @65  #define	ENOTNAM		178	/* Not a XENIX named type file */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @66  #define	ENAVAIL		179	/* No XENIX semaphores available */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @67  #define	EISNAM		180	/* Is a named type file */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @68  #define	EREMOTEIO	181	/* Remote I/O error */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @69  #define	ENOMEDIUM	182	/* No medium found */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @70  #define	EMEDIUMTYPE	183	/* Wrong medium type */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @71  #define	ENOKEY		184	/* Required key not available */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @72  #define	EKEYEXPIRED	185	/* Key has expired */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @73  #define	EKEYREVOKED	186	/* Key has been revoked */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @74  #define	EKEYREJECTED	187	/* Key was rejected by service */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   75  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   76  /* We now return you to your regularly scheduled HPUX. */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16   77  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @78  #define	ENOTSOCK	216	/* Socket operation on non-socket */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @79  #define	EDESTADDRREQ	217	/* Destination address required */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @80  #define	EMSGSIZE	218	/* Message too long */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @81  #define	EPROTOTYPE	219	/* Protocol wrong type for socket */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @82  #define	ENOPROTOOPT	220	/* Protocol not available */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @83  #define	EPROTONOSUPPORT	221	/* Protocol not supported */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @84  #define	ESOCKTNOSUPPORT	222	/* Socket type not supported */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @85  #define	EOPNOTSUPP	223	/* Operation not supported on transport endpoint */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @86  #define	EPFNOSUPPORT	224	/* Protocol family not supported */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @87  #define	EAFNOSUPPORT	225	/* Address family not supported by protocol */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @88  #define	EADDRINUSE	226	/* Address already in use */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @89  #define	EADDRNOTAVAIL	227	/* Cannot assign requested address */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @90  #define	ENETDOWN	228	/* Network is down */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @91  #define	ENETUNREACH	229	/* Network is unreachable */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @92  #define	ENETRESET	230	/* Network dropped connection because of reset */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @93  #define	ECONNABORTED	231	/* Software caused connection abort */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @94  #define	ECONNRESET	232	/* Connection reset by peer */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @95  #define	ENOBUFS		233	/* No buffer space available */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @96  #define	EISCONN		234	/* Transport endpoint is already connected */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @97  #define	ENOTCONN	235	/* Transport endpoint is not connected */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @98  #define	ESHUTDOWN	236	/* Cannot send after transport endpoint shutdown */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  @99  #define	ETOOMANYREFS	237	/* Too many references: cannot splice */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @100  #define	ETIMEDOUT	238	/* Connection timed out */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @101  #define	ECONNREFUSED	239	/* Connection refused */
3eb53b20d7bd137 arch/parisc/include/uapi/asm/errno.h Helge Deller        2016-08-20  102  #define	EREFUSED	ECONNREFUSED	/* for HP's NFS apparently */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @103  #define	EHOSTDOWN	241	/* Host is down */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @104  #define	EHOSTUNREACH	242	/* No route to host */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  105  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @106  #define	EALREADY	244	/* Operation already in progress */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @107  #define	EINPROGRESS	245	/* Operation now in progress */
f5a408d53edef3a arch/parisc/include/uapi/asm/errno.h Guy Martin          2014-01-16  108  #define	EWOULDBLOCK	EAGAIN	/* Operation would block (Not HPUX compliant) */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @109  #define	ENOTEMPTY	247	/* Directory not empty */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @110  #define	ENAMETOOLONG	248	/* File name too long */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @111  #define	ELOOP		249	/* Too many symbolic links encountered */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16 @112  #define	ENOSYS		251	/* Function not implemented */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  113  
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  114  #define ECANCELLED	253	/* aio request was canceled before complete (POSIX.4 / HPUX) */
05aa10de701409b include/asm-parisc/errno.h           Grant Grundler      2005-10-21 @115  #define ECANCELED	ECANCELLED	/* SuSv3 and Solaris wants one 'L' */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  116  
4750e2c0c59e0c8 include/asm-parisc/errno.h           Joe Korty           2005-05-01  117  /* for robust mutexes */
4750e2c0c59e0c8 include/asm-parisc/errno.h           Joe Korty           2005-05-01 @118  #define EOWNERDEAD	254	/* Owner died */
4750e2c0c59e0c8 include/asm-parisc/errno.h           Joe Korty           2005-05-01 @119  #define ENOTRECOVERABLE	255	/* State not recoverable */
4750e2c0c59e0c8 include/asm-parisc/errno.h           Joe Korty           2005-05-01  120  
7d217d7ffc3433d arch/parisc/include/asm/errno.h      Alexander Beregalov 2009-06-07 @121  #define	ERFKILL		256	/* Operation not possible due to RF-kill */
^1da177e4c3f415 include/asm-parisc/errno.h           Linus Torvalds      2005-04-16  122  
69ebb83e13e5142 arch/parisc/include/asm/errno.h      Ying Huang          2011-01-30 @123  #define EHWPOISON	257	/* Memory page has hardware error */
69ebb83e13e5142 arch/parisc/include/asm/errno.h      Ying Huang          2011-01-30  124  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki