{"id":2220379,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2220379/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-aspeed/patch/20260407-irqchip-v5-3-c0b0a300a057@aspeedtech.com/","project":{"id":57,"url":"http://patchwork.ozlabs.org/api/1.1/projects/57/?format=json","name":"Linux ASPEED SoC development","link_name":"linux-aspeed","list_id":"linux-aspeed.lists.ozlabs.org","list_email":"linux-aspeed@lists.ozlabs.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260407-irqchip-v5-3-c0b0a300a057@aspeedtech.com>","date":"2026-04-07T03:08:06","name":"[v5,3/4] irqchip/ast2700-intc: Add KUnit tests for route resolution","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"ec7f880a05e2bb7ff97a6c3d1fe98f90a7472ea0","submitter":{"id":71489,"url":"http://patchwork.ozlabs.org/api/1.1/people/71489/?format=json","name":"Ryan Chen","email":"ryan_chen@aspeedtech.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-aspeed/patch/20260407-irqchip-v5-3-c0b0a300a057@aspeedtech.com/mbox/","series":[{"id":498915,"url":"http://patchwork.ozlabs.org/api/1.1/series/498915/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-aspeed/list/?series=498915","date":"2026-04-07T03:08:04","name":"AST2700-A2 interrupt controller hierarchy and route support","version":5,"mbox":"http://patchwork.ozlabs.org/series/498915/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2220379/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2220379/checks/","tags":{},"headers":{"Return-Path":"\n <linux-aspeed+bounces-3849-incoming=patchwork.ozlabs.org@lists.ozlabs.org>","X-Original-To":["incoming@patchwork.ozlabs.org","linux-aspeed@lists.ozlabs.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org\n (client-ip=2404:9400:21b9:f100::1; helo=lists.ozlabs.org;\n envelope-from=linux-aspeed+bounces-3849-incoming=patchwork.ozlabs.org@lists.ozlabs.org;\n receiver=patchwork.ozlabs.org)","lists.ozlabs.org;\n arc=none smtp.remote-ip=211.20.114.72","lists.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com","lists.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=aspeedtech.com\n (client-ip=211.20.114.72; helo=twmbx01.aspeed.com;\n envelope-from=ryan_chen@aspeedtech.com; receiver=lists.ozlabs.org)"],"Received":["from lists.ozlabs.org (lists.ozlabs.org\n [IPv6:2404:9400:21b9:f100::1])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1 raw public key)\n server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fqWNs73xvz1yGM\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 07 Apr 2026 13:08:29 +1000 (AEST)","from boromir.ozlabs.org (localhost [127.0.0.1])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 4fqWNs3J6Rz2ygp;\n\tTue, 07 Apr 2026 13:08:29 +1000 (AEST)","from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 4fqWNr2xSPz2xQs\n\tfor <linux-aspeed@lists.ozlabs.org>; Tue, 07 Apr 2026 13:08:28 +1000 (AEST)","from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com\n (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 7 Apr\n 2026 11:08:05 +0800","from [127.0.1.1] (192.168.10.13) by TWMBX01.aspeed.com\n (192.168.0.62) with Microsoft SMTP Server id 15.2.1748.10 via Frontend\n Transport; Tue, 7 Apr 2026 11:08:05 +0800"],"ARC-Seal":"i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1775531309;\n\tcv=none;\n b=kh/rp5rVyvVnkJENIcFQhGKPzP7xKUL+EXdLO7UlbA8N4jWOliXZQzDl+aCjIfjXTPVOv1irScTzXq8DEwUUIYlYiTQATKBPtk06GZYRSxDf2Yot3QBAunwo1yynDC//obsdihcGWHE36MSFzejmKGLkSNGaZoiF7LGHm2H5DFqGcBY+IDz58glmLNsJY7J0vgSPJGrJ1NzeBHQS/FKLtv/hMCFEuoAEYM9V2Ao2vHZ+FM+CjQs6by7f7m37Ay8V/VlAdADtVQJCE2QGHZNKUuB5jlc0Qcrm4AjUL6l0om3IQ7gXSNediDkIn7Lh60r2ISJnR3HIHmuZ37ey2Z+i7Q==","ARC-Message-Signature":"i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707;\n\tt=1775531309; c=relaxed/relaxed;\n\tbh=jvXGsbLmIHtwxyCYQjYEdWkWVArvaM4bhcpAj1sYMb8=;\n\th=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References:\n\t In-Reply-To:To:CC;\n b=F7uFVBjh2Aepg6deQBNTjhFrZYD611Sr5LG0qaaUl1spN7YvELRkgKyidtfqbkv1TSyKJqP6NzxwA+9CC3gMirjMW6xQX7d8UlCmvsajXRCiC4oyPUuiGGQDJ29UTJU7m3jzmt9gfpfXKANtAazCGDmPyquycD6uaPpg/2HhYh3M1YwwOcyim5FL1GCvpDKM4NSAOATZ3zALNRnwitTOehssCIwu/HflxBceWYnXS5cmYA08CwaFLGCo3xUMhSKOAp12ZBFbSTYM5mD0uS8kEDoP9MAUm0uaIYb8dIcI3wzsxjC5OhsgaD0jLdMmwDH5XvaspSO1lX2keDVca2SwrA==","ARC-Authentication-Results":"i=1; lists.ozlabs.org;\n dmarc=pass (p=quarantine dis=none) header.from=aspeedtech.com;\n spf=pass (client-ip=211.20.114.72; helo=twmbx01.aspeed.com;\n envelope-from=ryan_chen@aspeedtech.com;\n receiver=lists.ozlabs.org) smtp.mailfrom=aspeedtech.com","From":"Ryan Chen <ryan_chen@aspeedtech.com>","Date":"Tue, 7 Apr 2026 11:08:06 +0800","Subject":"[PATCH v5 3/4] irqchip/ast2700-intc: Add KUnit tests for route\n resolution","X-Mailing-List":"linux-aspeed@lists.ozlabs.org","List-Id":"<linux-aspeed.lists.ozlabs.org>","List-Help":"<mailto:linux-aspeed+help@lists.ozlabs.org>","List-Owner":"<mailto:linux-aspeed+owner@lists.ozlabs.org>","List-Post":"<mailto:linux-aspeed@lists.ozlabs.org>","List-Archive":"<https://lore.kernel.org/linux-aspeed/>,\n  <https://lists.ozlabs.org/pipermail/linux-aspeed/>","List-Subscribe":"<mailto:linux-aspeed+subscribe@lists.ozlabs.org>,\n  <mailto:linux-aspeed+subscribe-digest@lists.ozlabs.org>,\n  <mailto:linux-aspeed+subscribe-nomail@lists.ozlabs.org>","List-Unsubscribe":"<mailto:linux-aspeed+unsubscribe@lists.ozlabs.org>","Precedence":"list","MIME-Version":"1.0","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"7bit","Message-ID":"<20260407-irqchip-v5-3-c0b0a300a057@aspeedtech.com>","References":"<20260407-irqchip-v5-0-c0b0a300a057@aspeedtech.com>","In-Reply-To":"<20260407-irqchip-v5-0-c0b0a300a057@aspeedtech.com>","To":"Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,\n\tConor Dooley <conor+dt@kernel.org>, Joel Stanley <joel@jms.id.au>, \"Andrew\n Jeffery\" <andrew@codeconstruct.com.au>, Paul Walmsley <pjw@kernel.org>,\n\t\"Palmer Dabbelt\" <palmer@dabbelt.com>, Albert Ou <aou@eecs.berkeley.edu>,\n\t\"Alexandre Ghiti\" <alex@ghiti.fr>, Thomas Gleixner <tglx@kernel.org>, Thomas\n Gleixner <tglx@kernel.org>","CC":"<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,\n\t<linux-arm-kernel@lists.infradead.org>, <linux-aspeed@lists.ozlabs.org>,\n\t<linux-riscv@lists.infradead.org>, Ryan Chen <ryan_chen@aspeedtech.com>","X-Mailer":"b4 0.14.3","X-Developer-Signature":"v=1; a=ed25519-sha256; t=1775531284; l=15577;\n i=ryan_chen@aspeedtech.com; s=20251126; h=from:subject:message-id;\n bh=0sLR6BB/w8nrHF2voMDdQ7Ck+6iZYGuYex8Z6iat808=;\n b=oALstVX3nuBZA6On1anELklfPOi4sb15t/Mw9LA3R2Wl4h0K392+r1zeSypxVWg6BIQbyz6qL\n peuSMDBUtOsB4s/dfldK7D5g9tLxpEOqXjFo8BnJVWxOWLvtVOPiH2J","X-Developer-Key":"i=ryan_chen@aspeedtech.com; a=ed25519;\n pk=Xe73xY6tcnkuRjjbVAB/oU30KdB3FvG4nuJuILj7ZVc=","X-Spam-Status":"No, score=0.0 required=5.0 tests=SPF_HELO_FAIL,SPF_PASS\n\tautolearn=disabled version=4.0.1","X-Spam-Checker-Version":"SpamAssassin 4.0.1 (2024-03-25) on lists.ozlabs.org"},"content":"Add a KUnit suite for aspeed_intc0_resolve_route().\n\nCover invalid arguments, invalid domain/range data, connected and\ndisconnected mappings, and malformed upstream range cases.\n\nSigned-off-by: Ryan Chen <ryan_chen@aspeedtech.com>\n\n---\nChanges in v5:\n- modify enable CONFIG_PROVE_LOCKING irq lock inversion dependency\n  detected.\nChanges in v4:\n- fix warning: the frame size of 1296 bytes is larger than 1280 bytes.\nChanges in v2:\n- add line break before include \"irq-ast2700.h\"\n- remove pointless newline.\n- rename arm_gicv3_fwnode_read_string_array to\n  gicv3_fwnode_read_string_array\n- add .kunitconfig file\n---\n drivers/irqchip/.kunitconfig             |   5 +\n drivers/irqchip/Kconfig                  |  11 +\n drivers/irqchip/Makefile                 |   1 +\n drivers/irqchip/irq-ast2700-intc0-test.c | 473 +++++++++++++++++++++++++++++++\n drivers/irqchip/irq-ast2700-intc0.c      |   3 +-\n 5 files changed, 492 insertions(+), 1 deletion(-)","diff":"diff --git a/drivers/irqchip/.kunitconfig b/drivers/irqchip/.kunitconfig\nnew file mode 100644\nindex 000000000000..00a12703f635\n--- /dev/null\n+++ b/drivers/irqchip/.kunitconfig\n@@ -0,0 +1,5 @@\n+CONFIG_KUNIT=y\n+CONFIG_OF=y\n+CONFIG_COMPILE_TEST=y\n+CONFIG_ASPEED_AST2700_INTC=y\n+CONFIG_ASPEED_AST2700_INTC_TEST=y\ndiff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig\nindex 0156fee89b2c..143af3f30a4b 100644\n--- a/drivers/irqchip/Kconfig\n+++ b/drivers/irqchip/Kconfig\n@@ -122,6 +122,17 @@ config ASPEED_AST2700_INTC\n \n \t  If unsure, say N.\n \n+config ASPEED_AST2700_INTC_TEST\n+\tbool \"Tests for the ASPEED AST2700 Interrupt Controller\"\n+\tdepends on ASPEED_AST2700_INTC && KUNIT=y\n+\tdefault KUNIT_ALL_TESTS\n+\thelp\n+\t  Enable KUnit tests for AST2700 INTC route resolution.\n+\t  The tests exercise error handling and route selection paths.\n+\t  This option is intended for test builds.\n+\n+\t  If unsure, say N.\n+\n config ATMEL_AIC_IRQ\n \tbool\n \tselect GENERIC_IRQ_CHIP\ndiff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile\nindex 62790663f982..ac04a4b97797 100644\n--- a/drivers/irqchip/Makefile\n+++ b/drivers/irqchip/Makefile\n@@ -90,6 +90,7 @@ obj-$(CONFIG_MVEBU_SEI)\t\t\t+= irq-mvebu-sei.o\n obj-$(CONFIG_LS_EXTIRQ)\t\t\t+= irq-ls-extirq.o\n obj-$(CONFIG_LS_SCFG_MSI)\t\t+= irq-ls-scfg-msi.o\n obj-$(CONFIG_ASPEED_AST2700_INTC)\t+= irq-ast2700.o irq-ast2700-intc0.o irq-ast2700-intc1.o\n+obj-$(CONFIG_ASPEED_AST2700_INTC_TEST)\t+= irq-ast2700-intc0-test.o\n obj-$(CONFIG_ARCH_ASPEED)\t\t+= irq-aspeed-vic.o irq-aspeed-i2c-ic.o irq-aspeed-scu-ic.o\n obj-$(CONFIG_ARCH_ASPEED)\t\t+= irq-aspeed-intc.o\n obj-$(CONFIG_STM32MP_EXTI)\t\t+= irq-stm32mp-exti.o\ndiff --git a/drivers/irqchip/irq-ast2700-intc0-test.c b/drivers/irqchip/irq-ast2700-intc0-test.c\nnew file mode 100644\nindex 000000000000..d49784509ac7\n--- /dev/null\n+++ b/drivers/irqchip/irq-ast2700-intc0-test.c\n@@ -0,0 +1,473 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ *  Copyright (C) 2026 Code Construct\n+ */\n+#include <kunit/test.h>\n+\n+#include \"irq-ast2700.h\"\n+\n+static void aspeed_intc0_resolve_route_bad_args(struct kunit *test)\n+{\n+\tstatic const struct aspeed_intc_interrupt_range c1ranges[] = { 0 };\n+\tstatic const u32 c1outs[] = { 0 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tconst struct irq_domain c0domain = { 0 };\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(NULL, 0, c1outs, 0, c1ranges, NULL);\n+\tKUNIT_EXPECT_EQ(test, rc, -EINVAL);\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, 0, c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_EQ(test, rc, -ENOENT);\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\t0, c1ranges, &resolved);\n+\tKUNIT_EXPECT_EQ(test, rc, -ENOENT);\n+}\n+\n+static int gicv3_fwnode_read_string_array(const struct fwnode_handle *fwnode,\n+\t\t\t\t\t  const char *propname, const char **val, size_t nval)\n+{\n+\tif (!propname)\n+\t\treturn -EINVAL;\n+\n+\tif (!val)\n+\t\treturn 1;\n+\n+\tif (WARN_ON(nval != 1))\n+\t\treturn -EOVERFLOW;\n+\n+\t*val = \"arm,gic-v3\";\n+\treturn 1;\n+}\n+\n+static const struct fwnode_operations arm_gicv3_fwnode_ops = {\n+\t.property_read_string_array = gicv3_fwnode_read_string_array,\n+};\n+\n+static void aspeed_intc_resolve_route_invalid_c0domain(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &arm_gicv3_fwnode_ops },\n+\t};\n+\tconst struct irq_domain c0domain = { .fwnode = &intc0_node.fwnode };\n+\tstatic const struct aspeed_intc_interrupt_range c1ranges[] = { 0 };\n+\tstatic const u32 c1outs[] = { 0 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_NE(test, rc, 0);\n+}\n+\n+static int\n+aspeed_intc0_fwnode_read_string_array(const struct fwnode_handle *fwnode_handle,\n+\t\t\t\t      const char *propname, const char **val,\n+\t\t\t\t      size_t nval)\n+{\n+\tif (!propname)\n+\t\treturn -EINVAL;\n+\n+\tif (!val)\n+\t\treturn 1;\n+\n+\tif (WARN_ON(nval != 1))\n+\t\treturn -EOVERFLOW;\n+\n+\t*val = \"aspeed,ast2700-intc0\";\n+\treturn nval;\n+}\n+\n+static const struct fwnode_operations intc0_fwnode_ops = {\n+\t.property_read_string_array = aspeed_intc0_fwnode_read_string_array,\n+};\n+\n+static void\n+aspeed_intc0_resolve_route_c1i1o1c0i1o1_connected(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &intc0_fwnode_ops },\n+\t};\n+\tstruct aspeed_intc_interrupt_range c1ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 1,\n+\t\t\t\t.param = { 128 }\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstatic const u32 c1outs[] = { 0 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tstruct aspeed_intc_interrupt_range intc0_ranges[] = {\n+\t\t{\n+\t\t\t.start = 128,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = { 0 },\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstruct aspeed_intc0 intc0 = {\n+\t\t.ranges = { .ranges = intc0_ranges, .nranges = ARRAY_SIZE(intc0_ranges), }\n+\t};\n+\tconst struct irq_domain c0domain = {\n+\t\t.host_data = &intc0,\n+\t\t.fwnode = &intc0_node.fwnode\n+\t};\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_EQ(test, rc, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.start, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.count, 1);\n+\tKUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 128);\n+}\n+\n+static void\n+aspeed_intc0_resolve_route_c1i1o1c0i1o1_disconnected(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &intc0_fwnode_ops },\n+\t};\n+\tstruct aspeed_intc_interrupt_range c1ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 1,\n+\t\t\t\t.param = { 128 }\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstatic const u32 c1outs[] = { 0 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tstruct aspeed_intc_interrupt_range intc0_ranges[] = {\n+\t\t{\n+\t\t\t.start = 129,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = { 0 },\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstruct aspeed_intc0 intc0 = {\n+\t\t.ranges = {\n+\t\t\t.ranges = intc0_ranges,\n+\t\t\t.nranges = ARRAY_SIZE(intc0_ranges),\n+\t\t}\n+\t};\n+\tconst struct irq_domain c0domain = {\n+\t\t.host_data = &intc0,\n+\t\t.fwnode = &intc0_node.fwnode\n+\t};\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_NE(test, rc, 0);\n+}\n+\n+static void aspeed_intc0_resolve_route_c1i1o1mc0i1o1(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &intc0_fwnode_ops },\n+\t};\n+\tstruct aspeed_intc_interrupt_range c1ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 1,\n+\t\t\t\t.param = { 480 }\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstatic const u32 c1outs[] = { 0 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tstruct aspeed_intc_interrupt_range intc0_ranges[] = {\n+\t\t{\n+\t\t\t.start = 192,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = { 0 },\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstruct aspeed_intc0 intc0 = {\n+\t\t.ranges = {\n+\t\t\t.ranges = intc0_ranges,\n+\t\t\t.nranges = ARRAY_SIZE(intc0_ranges),\n+\t\t}\n+\t};\n+\tconst struct irq_domain c0domain = {\n+\t\t.host_data = &intc0,\n+\t\t.fwnode = &intc0_node.fwnode\n+\t};\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_EQ(test, rc, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.start, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.count, 1);\n+\tKUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 480);\n+}\n+\n+static void aspeed_intc0_resolve_route_c1i2o2mc0i1o1(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &intc0_fwnode_ops },\n+\t};\n+\tstruct aspeed_intc_interrupt_range c1ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 1,\n+\t\t\t\t.param = { 480 }\n+\t\t\t}\n+\t\t},\n+\t\t{\n+\t\t\t.start = 1,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 1,\n+\t\t\t\t.param = { 510 }\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstatic const u32 c1outs[] = { 1 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tstatic struct aspeed_intc_interrupt_range intc0_ranges[] = {\n+\t\t{\n+\t\t\t.start = 208,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = { 0 },\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstruct aspeed_intc0 intc0 = {\n+\t\t.ranges = {\n+\t\t\t.ranges = intc0_ranges,\n+\t\t\t.nranges = ARRAY_SIZE(intc0_ranges),\n+\t\t}\n+\t};\n+\tconst struct irq_domain c0domain = {\n+\t\t.host_data = &intc0,\n+\t\t.fwnode = &intc0_node.fwnode\n+\t};\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_EQ(test, rc, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.start, 1);\n+\tKUNIT_EXPECT_EQ(test, resolved.count, 1);\n+\tKUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 510);\n+}\n+\n+static void aspeed_intc0_resolve_route_c1i1o1mc0i2o1(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &intc0_fwnode_ops },\n+\t};\n+\tstruct aspeed_intc_interrupt_range c1ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 1,\n+\t\t\t\t.param = { 510 }\n+\t\t\t}\n+\t\t},\n+\t};\n+\tstatic const u32 c1outs[] = { 0 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tstatic struct aspeed_intc_interrupt_range intc0_ranges[] = {\n+\t\t{\n+\t\t\t.start = 192,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = {0},\n+\t\t\t}\n+\t\t},\n+\t\t{\n+\t\t\t.start = 208,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = {0},\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstruct aspeed_intc0 intc0 = {\n+\t\t.ranges = {\n+\t\t\t.ranges = intc0_ranges,\n+\t\t\t.nranges = ARRAY_SIZE(intc0_ranges),\n+\t\t}\n+\t};\n+\tconst struct irq_domain c0domain = {\n+\t\t.host_data = &intc0,\n+\t\t.fwnode = &intc0_node.fwnode\n+\t};\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_EQ(test, rc, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.start, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.count, 1);\n+\tKUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 510);\n+}\n+\n+static void aspeed_intc0_resolve_route_c1i1o2mc0i1o1_invalid(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &intc0_fwnode_ops },\n+\t};\n+\tstruct aspeed_intc_interrupt_range c1ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 1,\n+\t\t\t\t.param = { 480 }\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstatic const u32 c1outs[] = {\n+\t\tAST2700_INTC_INVALID_ROUTE, 0\n+\t};\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tstruct aspeed_intc_interrupt_range intc0_ranges[] = {\n+\t\t{\n+\t\t\t.start = 192,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = { 0 },\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstruct aspeed_intc0 intc0 = {\n+\t\t.ranges = {\n+\t\t\t.ranges = intc0_ranges,\n+\t\t\t.nranges = ARRAY_SIZE(intc0_ranges),\n+\t\t}\n+\t};\n+\tconst struct irq_domain c0domain = {\n+\t\t.host_data = &intc0,\n+\t\t.fwnode = &intc0_node.fwnode\n+\t};\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_EQ(test, rc, 1);\n+\tKUNIT_EXPECT_EQ(test, resolved.start, 0);\n+\tKUNIT_EXPECT_EQ(test, resolved.count, 1);\n+\tKUNIT_EXPECT_EQ(test, resolved.upstream.param[0], 480);\n+}\n+\n+static void\n+aspeed_intc0_resolve_route_c1i1o1mc0i1o1_bad_range_upstream(struct kunit *test)\n+{\n+\tstruct device_node intc0_node = {\n+\t\t.fwnode = { .ops = &intc0_fwnode_ops },\n+\t};\n+\tstruct aspeed_intc_interrupt_range c1ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 1,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = &intc0_node.fwnode,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = { 0 }\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstatic const u32 c1outs[] = { 0 };\n+\tstruct aspeed_intc_interrupt_range resolved;\n+\tstruct aspeed_intc_interrupt_range intc0_ranges[] = {\n+\t\t{\n+\t\t\t.start = 0,\n+\t\t\t.count = 0,\n+\t\t\t.upstream = {\n+\t\t\t\t.fwnode = NULL,\n+\t\t\t\t.param_count = 0,\n+\t\t\t\t.param = { 0 },\n+\t\t\t}\n+\t\t}\n+\t};\n+\tstruct aspeed_intc0 intc0 = {\n+\t\t.ranges = {\n+\t\t\t.ranges = intc0_ranges,\n+\t\t\t.nranges = ARRAY_SIZE(intc0_ranges),\n+\t\t}\n+\t};\n+\tconst struct irq_domain c0domain = {\n+\t\t.host_data = &intc0,\n+\t\t.fwnode = &intc0_node.fwnode\n+\t};\n+\tint rc;\n+\n+\trc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,\n+\t\t\t\t\tARRAY_SIZE(c1ranges), c1ranges,\n+\t\t\t\t\t&resolved);\n+\tKUNIT_EXPECT_NE(test, rc, 0);\n+}\n+\n+static struct kunit_case ast2700_intc0_test_cases[] = {\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_bad_args),\n+\tKUNIT_CASE(aspeed_intc_resolve_route_invalid_c0domain),\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1c0i1o1_connected),\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1c0i1o1_disconnected),\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1mc0i1o1),\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_c1i2o2mc0i1o1),\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1mc0i2o1),\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_c1i1o2mc0i1o1_invalid),\n+\tKUNIT_CASE(aspeed_intc0_resolve_route_c1i1o1mc0i1o1_bad_range_upstream),\n+\t{},\n+};\n+\n+static struct kunit_suite ast2700_intc0_test_suite = {\n+\t.name = \"ast2700-intc0\",\n+\t.test_cases = ast2700_intc0_test_cases,\n+};\n+\n+kunit_test_suite(ast2700_intc0_test_suite);\n+\n+MODULE_LICENSE(\"GPL\");\ndiff --git a/drivers/irqchip/irq-ast2700-intc0.c b/drivers/irqchip/irq-ast2700-intc0.c\nindex 65e17b2dc6fa..14b8b88f1179 100644\n--- a/drivers/irqchip/irq-ast2700-intc0.c\n+++ b/drivers/irqchip/irq-ast2700-intc0.c\n@@ -311,7 +311,8 @@ int aspeed_intc0_resolve_route(const struct irq_domain *c0domain, size_t nc1outs\n \tif (nc1outs == 0 || nc1ranges == 0)\n \t\treturn -ENOENT;\n \n-\tif (!fwnode_device_is_compatible(c0domain->fwnode, \"aspeed,ast2700-intc0\"))\n+\tif (!IS_ENABLED(CONFIG_ASPEED_AST2700_INTC_TEST) &&\n+\t    !fwnode_device_is_compatible(c0domain->fwnode, \"aspeed,ast2700-intc0\"))\n \t\treturn -ENODEV;\n \n \tintc0 = c0domain->host_data;\n","prefixes":["v5","3/4"]}