Devicetree
 help / color / mirror / Atom feed
* [PATCH ath-next v5 5/6] wifi: ath12k: Add CE remap hardware parameters for IPQ5424
From: Raj Kumar Bhagat @ 2026-04-07  5:26 UTC (permalink / raw)
  To: Johannes Berg, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Raj Kumar Bhagat, Saravanakumar Duraisamy, Baochen Qiang
In-Reply-To: <20260407-ath12k-ipq5424-v5-0-8e96aa660ec4@oss.qualcomm.com>

From: Saravanakumar Duraisamy <quic_saradura@quicinc.com>

Add CE remap hardware parameters for Ath12k AHB device IPQ5424.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5424 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Signed-off-by: Saravanakumar Duraisamy <quic_saradura@quicinc.com>
Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/ce.h       | 13 +++++++++----
 drivers/net/wireless/ath/ath12k/wifi7/hw.c | 22 +++++++++++++++++-----
 2 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/ce.h b/drivers/net/wireless/ath/ath12k/ce.h
index df4f2a4f8480..009cddf2d68d 100644
--- a/drivers/net/wireless/ath/ath12k/ce.h
+++ b/drivers/net/wireless/ath/ath12k/ce.h
@@ -38,10 +38,15 @@
 #define PIPEDIR_INOUT		3 /* bidirectional */
 #define PIPEDIR_INOUT_H2H	4 /* bidirectional, host to host */
 
-/* CE address/mask */
-#define CE_HOST_IE_ADDRESS	0x75804C
-#define CE_HOST_IE_2_ADDRESS	0x758050
-#define CE_HOST_IE_3_ADDRESS	CE_HOST_IE_ADDRESS
+/* IPQ5332 CE address/mask */
+#define CE_HOST_IPQ5332_IE_ADDRESS	0x75804C
+#define CE_HOST_IPQ5332_IE_2_ADDRESS	0x758050
+#define CE_HOST_IPQ5332_IE_3_ADDRESS	CE_HOST_IPQ5332_IE_ADDRESS
+
+/* IPQ5424 CE address/mask */
+#define CE_HOST_IPQ5424_IE_ADDRESS	0x21804C
+#define CE_HOST_IPQ5424_IE_2_ADDRESS	0x218050
+#define CE_HOST_IPQ5424_IE_3_ADDRESS	CE_HOST_IPQ5424_IE_ADDRESS
 
 #define CE_HOST_IE_3_SHIFT	0xC
 
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index 2b5d1f7e9e04..cb3185850439 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -329,9 +329,15 @@ static const struct ath12k_hw_ring_mask ath12k_wifi7_hw_ring_mask_wcn7850 = {
 };
 
 static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5332 = {
-	.ie1_reg_addr = CE_HOST_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
-	.ie2_reg_addr = CE_HOST_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
-	.ie3_reg_addr = CE_HOST_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
+	.ie1_reg_addr = CE_HOST_IPQ5332_IE_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
+	.ie2_reg_addr = CE_HOST_IPQ5332_IE_2_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
+	.ie3_reg_addr = CE_HOST_IPQ5332_IE_3_ADDRESS - HAL_IPQ5332_CE_WFSS_REG_BASE,
+};
+
+static const struct ce_ie_addr ath12k_wifi7_ce_ie_addr_ipq5424 = {
+	.ie1_reg_addr = CE_HOST_IPQ5424_IE_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
+	.ie2_reg_addr = CE_HOST_IPQ5424_IE_2_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
+	.ie3_reg_addr = CE_HOST_IPQ5424_IE_3_ADDRESS - HAL_IPQ5424_CE_WFSS_REG_BASE,
 };
 
 static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = {
@@ -340,6 +346,12 @@ static const struct ce_remap ath12k_wifi7_ce_remap_ipq5332 = {
 	.cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET,
 };
 
+static const struct ce_remap ath12k_wifi7_ce_remap_ipq5424 = {
+	.base = HAL_IPQ5424_CE_WFSS_REG_BASE,
+	.size = HAL_IPQ5424_CE_SIZE,
+	.cmem_offset = HAL_SEQ_WCSS_CMEM_OFFSET,
+};
+
 static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 	{
 		.name = "qcn9274 hw1.0",
@@ -824,8 +836,8 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 		.iova_mask = 0,
 		.supports_aspm = false,
 
-		.ce_ie_addr = NULL,
-		.ce_remap = NULL,
+		.ce_ie_addr = &ath12k_wifi7_ce_ie_addr_ipq5424,
+		.ce_remap = &ath12k_wifi7_ce_remap_ipq5424,
 		.bdf_addr_offset = 0x940000,
 
 		.current_cc_support = false,

-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v5 4/6] wifi: ath12k: add ath12k_hw_regs for IPQ5424
From: Raj Kumar Bhagat @ 2026-04-07  5:26 UTC (permalink / raw)
  To: Johannes Berg, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Raj Kumar Bhagat, Saravanakumar Duraisamy, Baochen Qiang
In-Reply-To: <20260407-ath12k-ipq5424-v5-0-8e96aa660ec4@oss.qualcomm.com>

From: Saravanakumar Duraisamy <quic_saradura@quicinc.com>

Add register addresses (ath12k_hw_regs) for ath12k AHB based
WiFi 7 device IPQ5424.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5424 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Signed-off-by: Saravanakumar Duraisamy <quic_saradura@quicinc.com>
Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/wifi7/hal.c        |  2 +-
 drivers/net/wireless/ath/ath12k/wifi7/hal.h        |  3 +
 .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.c    | 88 ++++++++++++++++++++++
 .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.h    |  1 +
 4 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c
index c2cc99a83f09..a0a1902fb491 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c
@@ -55,7 +55,7 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = {
 		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact),
 		.tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274,
 		.hal_params = &ath12k_hw_hal_params_ipq5332,
-		.hw_regs = NULL,
+		.hw_regs = &ipq5424_regs,
 	},
 };
 
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.h b/drivers/net/wireless/ath/ath12k/wifi7/hal.h
index 9337225a5253..3d9386198893 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.h
@@ -364,6 +364,9 @@
 #define HAL_IPQ5332_CE_WFSS_REG_BASE	0x740000
 #define HAL_IPQ5332_CE_SIZE		0x100000
 
+#define HAL_IPQ5424_CE_WFSS_REG_BASE	0x200000
+#define HAL_IPQ5424_CE_SIZE		0x100000
+
 #define HAL_RX_MAX_BA_WINDOW	256
 
 #define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_USEC	(100 * 1000)
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c
index 41c918eb1767..ba9ce1e718e8 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c
@@ -484,6 +484,94 @@ const struct ath12k_hw_regs ipq5332_regs = {
 		HAL_IPQ5332_CE_WFSS_REG_BASE,
 };
 
+const struct ath12k_hw_regs ipq5424_regs = {
+	/* SW2TCL(x) R0 ring configuration address */
+	.tcl1_ring_id = 0x00000918,
+	.tcl1_ring_misc = 0x00000920,
+	.tcl1_ring_tp_addr_lsb = 0x0000092c,
+	.tcl1_ring_tp_addr_msb = 0x00000930,
+	.tcl1_ring_consumer_int_setup_ix0 = 0x00000940,
+	.tcl1_ring_consumer_int_setup_ix1 = 0x00000944,
+	.tcl1_ring_msi1_base_lsb = 0x00000958,
+	.tcl1_ring_msi1_base_msb = 0x0000095c,
+	.tcl1_ring_base_lsb = 0x00000910,
+	.tcl1_ring_base_msb = 0x00000914,
+	.tcl1_ring_msi1_data = 0x00000960,
+	.tcl2_ring_base_lsb = 0x00000988,
+	.tcl_ring_base_lsb = 0x00000b68,
+
+	/* TCL STATUS ring address */
+	.tcl_status_ring_base_lsb = 0x00000d48,
+
+	/* REO DEST ring address */
+	.reo2_ring_base = 0x00000578,
+	.reo1_misc_ctrl_addr = 0x00000b9c,
+	.reo1_sw_cookie_cfg0 = 0x0000006c,
+	.reo1_sw_cookie_cfg1 = 0x00000070,
+	.reo1_qdesc_lut_base0 = 0x00000074,
+	.reo1_qdesc_lut_base1 = 0x00000078,
+	.reo1_ring_base_lsb = 0x00000500,
+	.reo1_ring_base_msb = 0x00000504,
+	.reo1_ring_id = 0x00000508,
+	.reo1_ring_misc = 0x00000510,
+	.reo1_ring_hp_addr_lsb = 0x00000514,
+	.reo1_ring_hp_addr_msb = 0x00000518,
+	.reo1_ring_producer_int_setup = 0x00000524,
+	.reo1_ring_msi1_base_lsb = 0x00000548,
+	.reo1_ring_msi1_base_msb = 0x0000054C,
+	.reo1_ring_msi1_data = 0x00000550,
+	.reo1_aging_thres_ix0 = 0x00000B28,
+	.reo1_aging_thres_ix1 = 0x00000B2C,
+	.reo1_aging_thres_ix2 = 0x00000B30,
+	.reo1_aging_thres_ix3 = 0x00000B34,
+
+	/* REO Exception ring address */
+	.reo2_sw0_ring_base = 0x000008c0,
+
+	/* REO Reinject ring address */
+	.sw2reo_ring_base = 0x00000320,
+	.sw2reo1_ring_base = 0x00000398,
+
+	/* REO cmd ring address */
+	.reo_cmd_ring_base = 0x000002A8,
+
+	/* REO status ring address */
+	.reo_status_ring_base = 0x00000aa0,
+
+	/* WBM idle link ring address */
+	.wbm_idle_ring_base_lsb = 0x00000d3c,
+	.wbm_idle_ring_misc_addr = 0x00000d4c,
+	.wbm_r0_idle_list_cntl_addr = 0x00000240,
+	.wbm_r0_idle_list_size_addr = 0x00000244,
+	.wbm_scattered_ring_base_lsb = 0x00000250,
+	.wbm_scattered_ring_base_msb = 0x00000254,
+	.wbm_scattered_desc_head_info_ix0 = 0x00000260,
+	.wbm_scattered_desc_head_info_ix1	= 0x00000264,
+	.wbm_scattered_desc_tail_info_ix0 = 0x00000270,
+	.wbm_scattered_desc_tail_info_ix1 = 0x00000274,
+	.wbm_scattered_desc_ptr_hp_addr = 0x0000027c,
+
+	/* SW2WBM release ring address */
+	.wbm_sw_release_ring_base_lsb = 0x0000037c,
+
+	/* WBM2SW release ring address */
+	.wbm0_release_ring_base_lsb = 0x00000e08,
+	.wbm1_release_ring_base_lsb = 0x00000e80,
+
+	/* PPE release ring address */
+	.ppe_rel_ring_base = 0x0000046c,
+
+	/* CE address */
+	.umac_ce0_src_reg_base = 0x00200000 -
+		HAL_IPQ5424_CE_WFSS_REG_BASE,
+	.umac_ce0_dest_reg_base = 0x00201000 -
+		HAL_IPQ5424_CE_WFSS_REG_BASE,
+	.umac_ce1_src_reg_base = 0x00202000 -
+		HAL_IPQ5424_CE_WFSS_REG_BASE,
+	.umac_ce1_dest_reg_base = 0x00203000 -
+		HAL_IPQ5424_CE_WFSS_REG_BASE,
+};
+
 static inline
 bool ath12k_hal_rx_desc_get_first_msdu_qcn9274(struct hal_rx_desc *desc)
 {
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h
index 08c0a0469474..03cf3792d523 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.h
@@ -17,6 +17,7 @@ extern const struct hal_ops hal_qcn9274_ops;
 extern const struct ath12k_hw_regs qcn9274_v1_regs;
 extern const struct ath12k_hw_regs qcn9274_v2_regs;
 extern const struct ath12k_hw_regs ipq5332_regs;
+extern const struct ath12k_hw_regs ipq5424_regs;
 extern const struct ath12k_hal_tcl_to_wbm_rbm_map
 ath12k_hal_tcl_to_wbm_rbm_map_qcn9274[DP_TCL_NUM_RING_MAX];
 extern const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274;

-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v5 3/6] wifi: ath12k: add ath12k_hw_version_map entry for IPQ5424
From: Raj Kumar Bhagat @ 2026-04-07  5:26 UTC (permalink / raw)
  To: Johannes Berg, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Raj Kumar Bhagat, Baochen Qiang
In-Reply-To: <20260407-ath12k-ipq5424-v5-0-8e96aa660ec4@oss.qualcomm.com>

Add a new ath12k_hw_version_map entry for the AHB based WiFi 7 device
IPQ5424.

Reuse most of the ath12k_hw_version_map fields such as hal_ops,
hal_desc_sz, tcl_to_wbm_rbm_map, and hal_params from IPQ5332. The
register addresses differ on IPQ5424, hence set hw_regs temporarily
to NULL and populated it in a subsequent patch.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5424 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/wifi7/hal.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hal.c b/drivers/net/wireless/ath/ath12k/wifi7/hal.c
index bd1753ca0db6..c2cc99a83f09 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hal.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hal.c
@@ -50,6 +50,13 @@ static const struct ath12k_hw_version_map ath12k_wifi7_hw_ver_map[] = {
 		.hal_params = &ath12k_hw_hal_params_wcn7850,
 		.hw_regs = &qcc2072_regs,
 	},
+	[ATH12K_HW_IPQ5424_HW10] = {
+		.hal_ops = &hal_qcn9274_ops,
+		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9274_compact),
+		.tcl_to_wbm_rbm_map = ath12k_hal_tcl_to_wbm_rbm_map_qcn9274,
+		.hal_params = &ath12k_hw_hal_params_ipq5332,
+		.hw_regs = NULL,
+	},
 };
 
 int ath12k_wifi7_hal_init(struct ath12k_base *ab)

-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v5 2/6] wifi: ath12k: Add ath12k_hw_params for IPQ5424
From: Raj Kumar Bhagat @ 2026-04-07  5:26 UTC (permalink / raw)
  To: Johannes Berg, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Raj Kumar Bhagat, Saravanakumar Duraisamy, Baochen Qiang
In-Reply-To: <20260407-ath12k-ipq5424-v5-0-8e96aa660ec4@oss.qualcomm.com>

From: Saravanakumar Duraisamy <quic_saradura@quicinc.com>

Add ath12k_hw_params for the ath12k AHB-based WiFi 7 device IPQ5424.
The WiFi device IPQ5424 is similar to IPQ5332. Most of the hardware
parameters like hw_ops, wmi_init, ring_mask, etc., are the same between
IPQ5424 and IPQ5332, hence use these same parameters for IPQ5424.
Some parameters are specific to IPQ5424; initially set these to
0 or NULL, and populate them in subsequent patches.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
Tested-on: IPQ5424 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Signed-off-by: Saravanakumar Duraisamy <quic_saradura@quicinc.com>
Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/core.h     |  1 +
 drivers/net/wireless/ath/ath12k/wifi7/hw.c | 79 ++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)

diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 59c193b24764..68453594eba8 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -157,6 +157,7 @@ enum ath12k_hw_rev {
 	ATH12K_HW_WCN7850_HW20,
 	ATH12K_HW_IPQ5332_HW10,
 	ATH12K_HW_QCC2072_HW10,
+	ATH12K_HW_IPQ5424_HW10,
 };
 
 enum ath12k_firmware_mode {
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
index ec6dba96640b..2b5d1f7e9e04 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c
@@ -753,6 +753,85 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = {
 
 		.dp_primary_link_only = false,
 	},
+	{
+		.name = "ipq5424 hw1.0",
+		.hw_rev = ATH12K_HW_IPQ5424_HW10,
+		.fw = {
+			.dir = "IPQ5424/hw1.0",
+			.board_size = 256 * 1024,
+			.cal_offset = 128 * 1024,
+			.m3_loader = ath12k_m3_fw_loader_remoteproc,
+			.download_aux_ucode = false,
+		},
+		.max_radios = 1,
+		.single_pdev_only = false,
+		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332,
+		.internal_sleep_clock = false,
+
+		.hw_ops = &qcn9274_ops,
+		.ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332,
+
+		.host_ce_config = ath12k_wifi7_host_ce_config_ipq5332,
+		.ce_count = 12,
+		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332,
+		.target_ce_count = 12,
+		.svc_to_ce_map =
+			ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332,
+		.svc_to_ce_map_len = 18,
+
+		.rxdma1_enable = true,
+		.num_rxdma_per_pdev = 1,
+		.num_rxdma_dst_ring = 0,
+		.rx_mac_buf_ring = false,
+		.vdev_start_delay = false,
+
+		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
+				   BIT(NL80211_IFTYPE_AP) |
+				   BIT(NL80211_IFTYPE_MESH_POINT),
+		.supports_monitor = true,
+
+		.idle_ps = false,
+		.download_calib = true,
+		.supports_suspend = false,
+		.tcl_ring_retry = true,
+		.reoq_lut_support = false,
+		.supports_shadow_regs = false,
+
+		.num_tcl_banks = 48,
+		.max_tx_ring = 4,
+
+		.mhi_config = NULL,
+
+		.wmi_init = &ath12k_wifi7_wmi_init_qcn9274,
+
+		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
+
+		.rfkill_pin = 0,
+		.rfkill_cfg = 0,
+		.rfkill_on_level = 0,
+
+		.rddm_size = 0,
+
+		.def_num_link = 0,
+		.max_mlo_peer = 256,
+
+		.otp_board_id_register = 0,
+
+		.supports_sta_ps = false,
+
+		.acpi_guid = NULL,
+		.supports_dynamic_smps_6ghz = false,
+		.iova_mask = 0,
+		.supports_aspm = false,
+
+		.ce_ie_addr = NULL,
+		.ce_remap = NULL,
+		.bdf_addr_offset = 0x940000,
+
+		.current_cc_support = false,
+
+		.dp_primary_link_only = true,
+	},
 };
 
 /* Note: called under rcu_read_lock() */

-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v5 1/6] dt-bindings: net: wireless: add ath12k wifi device IPQ5424
From: Raj Kumar Bhagat @ 2026-04-07  5:26 UTC (permalink / raw)
  To: Johannes Berg, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Raj Kumar Bhagat, Krzysztof Kozlowski
In-Reply-To: <20260407-ath12k-ipq5424-v5-0-8e96aa660ec4@oss.qualcomm.com>

Add the device-tree bindings for the ATH12K AHB wifi device IPQ5424.

Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
 Documentation/devicetree/bindings/net/wireless/qcom,ipq5332-wifi.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ipq5332-wifi.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ipq5332-wifi.yaml
index 363a0ecb6ad9..37d8a0da7780 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ipq5332-wifi.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ipq5332-wifi.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - qcom,ipq5332-wifi
+      - qcom,ipq5424-wifi
 
   reg:
     maxItems: 1

-- 
2.34.1


^ permalink raw reply related

* [PATCH ath-next v5 0/6] wifi: ath12k: Enable IPQ5424 AHB WiFi device
From: Raj Kumar Bhagat @ 2026-04-07  5:26 UTC (permalink / raw)
  To: Johannes Berg, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Raj Kumar Bhagat, Saravanakumar Duraisamy, Baochen Qiang,
	Sowmiya Sree Elavalagan, Krzysztof Kozlowski

Add support for the new ath12k AHB device IPQ5424, as currently, Ath12k
AHB only supports IPQ5332 WiFi devices.

The IPQ5424 is an IEEE 802.11be 2 GHz WiFi device, supporting 4x4
configurations. To enable the IPQ5424 device:
- Add the necessary hardware parameters for IPQ5424.
- Modify the boot-up sequence for ath12k AHB to accommodate the
  requirements of the IPQ5424 device.

---
Changes in v5:
- The mhi_config and current_cc_support hardware parameters are explicitly
  initialized to default values.
- Link to v4: https://lore.kernel.org/r/20260402-ath12k-ipq5424-v4-0-cd1e0f0a6c88@oss.qualcomm.com

Changes in v4:
- DT binding: dropped copyright update as per discussion in v3.
- DT binding: Used DT binding from v2 and retained Acked-by tag.
- Link to v3: https://patch.msgid.link/20260331-ath12k-ipq5424-v3-0-1455b9cae29c@oss.qualcomm.com

Changes in v3:
- DT binding: updated copyright.
- DT binding: Dropped Acked-by tag as copyright is updated.
- Rebased on latest ToT.
- Dropped ath12k_ahb_ops because qcom_mdt_load() and
  qcom_mdt_load_no_init() now have different number of arguments.
- Link to v2: https://lore.kernel.org/all/20250518-ath12k-ipq5424-v2-0-ef81b833dc97@quicinc.com/

Changes in v2:
- DT binding: Removed the redundant example for IPQ5424, as it is similar
  to IPQ5332.
- Added driver probe data structure to eliminate the redundant switch-case
  logic in the ath12k_ahb_probe() function.
- Validation completed, hence changed from RFC to PATCH.
- Link to v1: https://lore.kernel.org/all/20250130051838.1924079-1-quic_rajkbhag@quicinc.com/

Signed-off-by: Raj Kumar Bhagat <raj.bhagat@oss.qualcomm.com>

---
Raj Kumar Bhagat (2):
      dt-bindings: net: wireless: add ath12k wifi device IPQ5424
      wifi: ath12k: add ath12k_hw_version_map entry for IPQ5424

Saravanakumar Duraisamy (3):
      wifi: ath12k: Add ath12k_hw_params for IPQ5424
      wifi: ath12k: add ath12k_hw_regs for IPQ5424
      wifi: ath12k: Add CE remap hardware parameters for IPQ5424

Sowmiya Sree Elavalagan (1):
      wifi: ath12k: Enable IPQ5424 WiFi device support

 .../bindings/net/wireless/qcom,ipq5332-wifi.yaml   |  1 +
 drivers/net/wireless/ath/ath12k/ahb.c              | 36 ++++----
 drivers/net/wireless/ath/ath12k/ahb.h              |  1 +
 drivers/net/wireless/ath/ath12k/ce.h               | 13 ++-
 drivers/net/wireless/ath/ath12k/core.h             |  1 +
 drivers/net/wireless/ath/ath12k/wifi7/ahb.c        |  8 ++
 drivers/net/wireless/ath/ath12k/wifi7/hal.c        |  7 ++
 drivers/net/wireless/ath/ath12k/wifi7/hal.h        |  3 +
 .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.c    | 88 ++++++++++++++++++++
 .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.h    |  1 +
 drivers/net/wireless/ath/ath12k/wifi7/hw.c         | 97 +++++++++++++++++++++-
 11 files changed, 235 insertions(+), 21 deletions(-)
---
base-commit: 15551ababf6d4e857f2101366a0c3eaa86dd822c
change-id: 20260331-ath12k-ipq5424-cddb63a46a97


^ permalink raw reply

* Re: [PATCH v4 01/11] dt-bindings: crypto: qcom,ice: Fix missing power-domain and iface clk
From: Kuldeep Singh @ 2026-04-07  4:58 UTC (permalink / raw)
  To: Harshal Dev, Herbert Xu, David S. Miller, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Abel Vesa, Manivannan Sadhasivam, cros-qcom-dts-watchers,
	Eric Biggers, Dmitry Baryshkov, Jingyi Wang, Tengfei Fan,
	Bartosz Golaszewski, David Wronek, Luca Weiss, Neil Armstrong,
	Melody Olvera, Alexander Koskovich, Rob Herring
  Cc: Brian Masney, Neeraj Soni, Gaurav Kashyap, linux-arm-msm,
	linux-crypto, devicetree, linux-kernel, Krzysztof Kozlowski,
	Konrad Dybcio, Krzysztof Kozlowski
In-Reply-To: <2b71dd68-ff35-411e-905d-3ffa2ea3efe4@oss.qualcomm.com>

On 3/31/2026 3:10 PM, Harshal Dev wrote:
> Hi Kuldeep,
> 
> On 3/24/2026 4:16 PM, Kuldeep Singh wrote:
>>
>> On 3/23/2026 2:47 PM, Harshal Dev wrote:
>>> The DT bindings for inline-crypto engine do not specify the UFS_PHY_GDSC
>>> power-domain and iface clock. Without enabling the iface clock and the
>>> associated power-domain the ICE hardware cannot function correctly and
>>> leads to unclocked hardware accesses being observed during probe.
>>>
>>> Fix the DT bindings for inline-crypto engine to require the UFS_PHY_GDSC
>>> power-domain and iface clock for new devices (Eliza and Milos) introduced
>>> in the current release (7.0) with yet-to-stabilize ABI, while preserving
>>> backward compatibility for older devices.
>>>
>>> Fixes: 618195a7ac3df ("dt-bindings: crypto: qcom,inline-crypto-engine: Document the Eliza ICE")
>>> Fixes: 85faec1e85555 ("dt-bindings: crypto: qcom,inline-crypto-engine: document the Milos ICE")
>>> Signed-off-by: Harshal Dev <harshal.dev@oss.qualcomm.com>
>>> ---
>>>  .../bindings/crypto/qcom,inline-crypto-engine.yaml | 35 +++++++++++++++++++++-
>>>  1 file changed, 34 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
>>> index 876bf90ed96e..ccb6b8dd8e11 100644
>>> --- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
>>> +++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
>>> @@ -30,6 +30,16 @@ properties:
>>>      maxItems: 1
>>>  
>>>    clocks:
>>> +    minItems: 1
>>> +    maxItems: 2
>>> +
>>> +  clock-names:
>>> +    minItems: 1
>>> +    items:
>>> +      - const: core
>>> +      - const: iface
>>> +
>>> +  power-domains:
>>>      maxItems: 1
>>>  
>>>    operating-points-v2: true
>>> @@ -44,6 +54,25 @@ required:
>>>  
>>>  additionalProperties: false
>>>  
>>> +allOf:
>>> +  - if:
>>> +      properties:
>>> +        compatible:
>>> +          contains:
>>> +            enum:
>>> +              - qcom,eliza-inline-crypto-engine
>>> +              - qcom,milos-inline-crypto-engine
>>> +
>>> +    then:
>>> +      required:
>>> +        - power-domains
>>> +        - clock-names
>>> +      properties:
>>> +        clocks:
>>> +          minItems: 2
>>> +        clock-names:
>>> +          minItems: 2
>>> +
>>
>> Hi Krzysztof,
>>
>> As motive here is to enforce 2 clocks for upcoming targets and keep
>> minItems as 1 for already merged ones for ensuring backward
>> compatibility. Can we do like below?
>>
>> allOf:
>>   - if:
>>       not:
>>         properties:
>>           compatible:
>>             contains:
>>               enum:
>>                 - qcom,kaanapali-inline-crypto-engine
>>                 - qcom,qcs8300-inline-crypto-engine
>>                 - qcom,sa8775p-inline-crypto-engine
>>                 - qcom,sc7180-inline-crypto-engine
>>                 - qcom,sc7280-inline-crypto-engine
>>                 - qcom,sm8450-inline-crypto-engine
>>                 - qcom,sm8550-inline-crypto-engine
>>                 - qcom,sm8650-inline-crypto-engine
>>                 - qcom,sm8750-inline-crypto-engine
>>
>>     then:
>>       required:
>>         - power-domains
>>         - clock-names
>>       properties:
>>         clocks:
>>           minItems: 2
>>         clock-names:
>>           minItems: 2
>>
>> This will ensure for every new target addition, default clock count is
>> enforced as 2 default.
>> Please share your thoughts as well.

Hi Rob/Krzysztof,

Were you able to review this suggestion?
Please let me know if need to update patch on top of this one to
initiate discussion.

One advantage i see with suggested approach:
For new target addition, just need to document new compatible string and
no need to update another list everytime.
It's easy to miss adding entry alongside eliza/milos and might make
wrong assumption to authors/dt-checker that 1 clock is still allowed.

>>
> 
> I don't really have any particular objections to this proposal, but I can
> see that other bindings where the need for an additional clock was realized
> later on use a similar pattern as this patchset does:
> https://elixir.bootlin.com/linux/v7.0-rc2/source/Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
> 

Sure Harshal, the current is doing what's intended to do.

For that,
Reviewed-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>

If not in this patch, maybe we can take this discussion in separate thread.

-- 
Regards
Kuldeep


^ permalink raw reply

* Re: [PATCH v3 00/15] firmware: qcom: Add OP-TEE PAS service support
From: Sumit Garg @ 2026-04-07  4:54 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
	netdev, linux-wireless, ath12k, linux-remoteproc, konradybcio,
	robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo, lumag,
	abhinav.kumar, jesszhan0024, marijn.suijten, airlied, simona,
	vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
	andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
	mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
	jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
	amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
	harshal.dev, linux-kernel, Sumit Garg
In-Reply-To: <adPLx3nCBb8IHz2b@baldur>

Hi Bjorn,

On Mon, Apr 06, 2026 at 10:09:27AM -0500, Bjorn Andersson wrote:
> On Fri, Mar 27, 2026 at 06:40:28PM +0530, Sumit Garg wrote:
> > From: Sumit Garg <sumit.garg@oss.qualcomm.com>
> > 
> > Qcom platforms has the legacy of using non-standard SCM calls
> > splintered over the various kernel drivers. These SCM calls aren't
> > compliant with the standard SMC calling conventions which is a
> > prerequisite to enable migration to the FF-A specifications from Arm.
> > 
> 
> Please get our colleagues involved in this discussion, because this
> non-SCM interface does not match the direction we are taking.

I thought I have already involved folks from QTEE perspective (Apurupa
and Sree) actively working on FF-A implementation aligned to this
interface. It would have been better if you could let me know where is
the direction mismatch here. In case there is a better alternative
design proposal for PAS service with FF-A, I would be happy to hear
that.

Anyhow for the legacy SoCs like KLMT, we really don't have any
alternative but have to stick to existing QTEE PAS design with OP-TEE
providing as an alternative backend. Surely we want to support loading
of existing signed firmware present in linux-firmware repo for KLMT with
OP-TEE being the TZ.

-Sumit

^ permalink raw reply

* Re: [PATCH v8 1/7] dt-bindings: input: syna,rmi4: Document syna,rmi4-s3706b
From: Dmitry Torokhov @ 2026-04-07  4:48 UTC (permalink / raw)
  To: David Heidelberg
  Cc: Kaustabh Chakraborty, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jason A. Donenfeld, Matthias Schiffer,
	Vincent Huang, Casey Connolly, linux-input, devicetree,
	linux-kernel, phone-devel, Krzysztof Kozlowski
In-Reply-To: <5630a4af-e18f-4daf-9b04-ea61091d9e51@ixit.cz>

On Wed, Mar 25, 2026 at 12:33:23PM +0100, David Heidelberg wrote:
> On 24/03/2026 20:42, Dmitry Torokhov wrote:
> > On Tue, Mar 24, 2026 at 08:40:34PM +0100, David Heidelberg via B4 Relay wrote:
> > > From: David Heidelberg <david@ixit.cz>
> > > 
> > > Mostly irrelevant for authentic Synaptics touchscreens, but very important
> > > for applying workarounds to cheap TS knockoffs.
> > > 
> > > These knockoffs work well with the downstream driver, and since the user
> > > has no way to distinguish them, later in this patch set, we introduce
> > > workarounds to ensure they function as well as possible.
> > > 
> > > Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> > > Signed-off-by: David Heidelberg <david@ixit.cz>
> > > ---
> > >   Documentation/devicetree/bindings/input/syna,rmi4.yaml | 11 ++++++++---
> > >   1 file changed, 8 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/input/syna,rmi4.yaml b/Documentation/devicetree/bindings/input/syna,rmi4.yaml
> > > index 8685ef4481f4a..fb4804ac3544d 100644
> > > --- a/Documentation/devicetree/bindings/input/syna,rmi4.yaml
> > > +++ b/Documentation/devicetree/bindings/input/syna,rmi4.yaml
> > > @@ -18,9 +18,14 @@ description: |
> > >   properties:
> > >     compatible:
> > > -    enum:
> > > -      - syna,rmi4-i2c
> > > -      - syna,rmi4-spi
> > > +    oneOf:
> > > +      - enum:
> > > +          - syna,rmi4-i2c
> > > +          - syna,rmi4-spi
> > > +      - items:
> > > +          - enum:
> > > +              - syna,rmi4-s3706b  # OnePlus 6/6T
> > 
> > I thought that all the workarounds will be keyed off this new
> > compatible, but I do not see that. What am I missing?
> 
> The compatible is used for sequence in the
> 
> Input: synaptics-rmi4 - support fallback values for PDT descriptor bytes
> 
> where it is used to provide values missing for OP6 (and possible others in
> the future, when added).
> 
> From my understanding the series, only two patches (1st and last) are
> specific for the OP6, rest will likely benefit various TS not implementing
> full Synaptics set. All measures apply only when touchscreen reports
> something wrong.

If the sensor does not implement RMI4 protocol properly it should not
use rmi4 compatibility. I will not apply any patches that work around
incomplete implementations unless they are triggered by a dedicated
compatible.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 1/2] arm64: dts: qcom: kodiak: Add iface clock for ice sdhc
From: Kuldeep Singh @ 2026-04-07  4:36 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <ggkj63sjoeqedsahze423723qs6tvcgmlnxqn2usqipve2yktp@45aas5zypfzr>

On 4/7/2026 12:43 AM, Dmitry Baryshkov wrote:
> On Mon, Apr 06, 2026 at 10:00:36PM +0530, Kuldeep Singh wrote:
>> Qualcomm in-line crypto engine (ICE) platform driver specifies and votes
>> for its own resources. Before accessing ICE hardware during probe, to
>> avoid potential unclocked register access issues (when clk_ignore_unused
>> is not passed on the kernel command line), in addition to the 'core'
>> clock the 'iface' clock should also be turned on by the driver.
>>
>> As bindings allow to specify 2 clocks, add iface clock now.
>>
>> Signed-off-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>
>> ---
>>  arch/arm64/boot/dts/qcom/kodiak.dtsi | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
>> index dda4697a61b7..5e6b659e8719 100644
>> --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
>> +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
>> @@ -1082,7 +1082,8 @@ sdhc_ice: crypto@7c8000 {
>>  			compatible = "qcom,sc7280-inline-crypto-engine",
>>  				     "qcom,inline-crypto-engine";
>>  			reg = <0x0 0x007c8000 0x0 0x18000>;
>> -			clocks = <&gcc GCC_SDCC1_ICE_CORE_CLK>;
>> +			clocks = <&gcc GCC_SDCC1_ICE_CORE_CLK>, <&gcc GCC_SDCC1_AHB_CLK>;
>> +			clock-names = "core", "iface";
> 
> Inside the schema the clocks have maxItems:1. Please update the schema:
> Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml

Thanks for review Dmitry.

Clocks maxItems are already 2 as per below dependent patch.
Kindly check cover letter for dependency to understand more.

https://lore.kernel.org/linux-arm-msm/20260323-qcom_ice_power_and_clk_vote-v4-0-e36044bbdfe9@oss.qualcomm.com/T/#m885402f4d828804501a3982ae8b8a5a028e15a89

-- 
Regards
Kuldeep


^ permalink raw reply

* Re: [PATCH 1/2] Revert "arm64: tegra: Disable ISO SMMU for Tegra194"
From: Mikko Perttunen @ 2026-04-07  4:09 UTC (permalink / raw)
  To: Thierry Reding, Aaron Kling
  Cc: Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jonathan Hunter, devicetree, linux-tegra, linux-kernel
In-Reply-To: <CALHNRZ8Zs2Zp80OgoU6R54=n76JgiYGbMvWD2iP9HpUFYO2big@mail.gmail.com>

On Monday, April 6, 2026 4:49 PM Aaron Kling wrote:
> On Tue, Feb 17, 2026 at 4:13 AM Thierry Reding
> <thierry.reding@kernel.org> wrote:
> >
> > On Tue, Feb 17, 2026 at 12:53:54PM +0900, Mikko Perttunen wrote:
> > > On Thursday, January 22, 2026 7:22 PM Mikko Perttunen wrote:
> > > > On Tuesday, December 9, 2025 1:21 PM Aaron Kling wrote:
> > > > > On Mon, Nov 3, 2025 at 12:05 PM Aaron Kling <webgeek1234@gmail.com> wrote:
> > > > > >
> > > > > > On Mon, Nov 3, 2025 at 5:07 AM Thierry Reding <thierry.reding@gmail.com> wrote:
> > > > > > >
> > > > > > > On Sat, Nov 01, 2025 at 06:13:26PM -0500, Aaron Kling wrote:
> > > > > > > > On Sat, Nov 1, 2025 at 6:01 PM Aaron Kling via B4 Relay
> > > > > > > > <devnull+webgeek1234.gmail.com@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > From: Aaron Kling <webgeek1234@gmail.com>
> > > > > > > > >
> > > > > > > > > This reverts commit ebea268ea583ba4970df425dfef8c8e21d0a4e12.
> > > > > > > > >
> > > > > > > > > Mmu is now being enabled for the display controllers.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Aaron Kling <webgeek1234@gmail.com>
> > > > > > > > > ---
> > > > > > > > >  arch/arm64/boot/dts/nvidia/tegra194.dtsi | 2 +-
> > > > > > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > > > > >
> > > > > > > > > diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
> > > > > > > > > index 1399342f23e1c4f73b278adc66dfb948fc30d326..854ed6d46aa1d8eedcdfbae1fdde1374adf40337 100644
> > > > > > > > > --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
> > > > > > > > > +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
> > > > > > > > > @@ -1807,7 +1807,7 @@ iommu@10000000 {
> > > > > > > > >                         #iommu-cells = <1>;
> > > > > > > > >
> > > > > > > > >                         nvidia,memory-controller = <&mc>;
> > > > > > > > > -                       status = "disabled";
> > > > > > > > > +                       status = "okay";
> > > > > > > > >                 };
> > > > > > > > >
> > > > > > > > >                 smmu: iommu@12000000 {
> > > > > > > > >
> > > > > > > > > --
> > > > > > > > > 2.51.0
> > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > > > Question for Jon as the author of the commit being reverted. The
> > > > > > > > commit message states "we do not have a way to pass frame-buffer
> > > > > > > > memory from the bootloader to the kernel". If I understand this
> > > > > > > > correctly, this is talking about seamless handoff. What does this have
> > > > > > > > to do with enabling mmu on the display controllers? Seamless does not
> > > > > > > > work on any tegra arch as far as I'm aware, but Tegra194 is the only
> > > > > > > > one that doesn't have mmu enabled for the dc's. But enabling mmu
> > > > > > > > allows for better and faster memory allocation. My initial attempts to
> > > > > > > > enable this didn't work because I tried to attach them to the main mmu
> > > > > > > > unit, see the related freedesktop issue [0]. After noticing in the
> > > > > > > > downstream dt that the dc's are on a separate unit, I made it work.
> > > > > > > > And so far, it seems to work just as well as Tegra186. Then when I was
> > > > > > > > packaging up the change to submit, I found that this had been
> > > > > > > > explicitly disabled. But I'm not seeing why. Am I missing some
> > > > > > > > additional factors?
> > > > > > >
> > > > > > > This isn't seamless handoff to the Tegra DRM driver for display, but
> > > > > > > rather to simple-framebuffer. While this does technically work, it also
> > > > > > > causes a spew of SMMU faults during early boot because the firmware does
> > > > > > > not properly pass the SMMU mapping information to the kernel.
> > > > > > >
> > > > > > > In a nutshell what happens is that the firmware sets up the display
> > > > > > > controller to scan out from a reserved memory region, but it does so
> > > > > > > without involving the SMMU, so it uses physical addresses directly. When
> > > > > > > the kernel boots and the SMMU is enabled the continued accesses from
> > > > > > > display hardware cause SMMU faults (because there is no mapping for the
> > > > > > > framebuffer addresses).
> > > > > > >
> > > > > > > That said, we did solve these issues and this may not be happening
> > > > > > > anymore with the most recent L4T releases, so it may be okay to revert
> > > > > > > this now. We should find out exactly which release includes all the
> > > > > > > needed changes so that it can be referenced in the commit message. I
> > > > > > > want to avoid people running new kernels with an old L4T release and
> > > > > > > then seeing these errors without any reference as to why that might
> > > > > > > suddenly happen.
> > > > > >
> > > > > > For reference, I have rolled back my Android usecase to use the L4T
> > > > > > r32.7.6 bootloaders on T194 for a variety of reasons. So I am using
> > > > > > cboot as the final bootloader and not edk2 as in L4T r34/r35. I have a
> > > > > > pending cboot patch to support simple-framebuffer handoff, but haven't
> > > > > > fully verified it as tegra-drm is currently unable to takeover from
> > > > > > simplefb like openrm does for t234. But all that to say that since I
> > > > > > no longer use r35 for t194 I don't have the setup to easily verify
> > > > > > which point release works here and what doesn't.
> > > > >
> > > > > Any further thoughts on this patch?
> > > > >
> > > > > Aaron
> > > >
> > > > FWIW,
> > > >
> > > > looks like the edk2 patch to update iommu-addresses --
> > > >
> > > > commit 6071946461389221d2314cbbae0377610b5b1f6a
> > > > Author: Jan Bobek <jbobek@nvidia.com>
> > > > Date:   Tue Mar 21 00:15:27 2023 +0000
> > > >
> > > >     feat(NvDisplayControllerDxe): update FDT with framebuffer info
> > > >
> > > >     On ready-to-boot and whenever FDT is installed, update FDT with
> > > >     framebuffer mode information, base address and size.
> > > >
> > > >     Signed-off-by: Jan Bobek <jbobek@nvidia.com>
> > > >     Reviewed-by: Ashish Singhal <ashishsingha@nvidia.com>
> > > >
> > > > is in since r36.2
> > > >
> > > > $ git tag --contains 6071946461389221d2314cbbae0377610b5b1f6a | grep "^r"
> > > > r36.2
> > > > r36.3.0
> > > > r36.4.0
> > > > r36.4.3
> > > > r36.4.4
> > > > r36.4.5
> > > > r38.2
> > > > r38.4
> > > >
> > > > Not so good for T194 since r36 only supports Orin.
> > > >
> > > > I'll look into getting this cherry-picked to r35.
> > > >
> > > > Mikko
> > > >
> > > >
> > >
> > > I looked into this and it appears a version of this is in r35, but it
> > > only supports T234. However, I also found that at one point, L4T
> > > bootloader configuration has been modified to place the display
> > > controllers into SMMU bypass until otherwise configured by the kernel
> > > -- which the kernel does in tegra_mc_probe_device.
> > >
> > > I think that means there is still potential for an issue where the
> > > display continues to be on between tegra_mc_probe_device and tegradrm
> > > reconfiguring it. However, I cannot reproduce that happening -- most
> > > likely the display is being turned off before that because of a clock
> > > or power domain being turned off.
> > >
> > > In any case, this means that we no longer need to pass the
> > > framebuffer's information to the kernel. I think it would be good to
> > > have some clarity to ensure the issue described above cannot happen,
> > > but otherwise we should be able to enable IOMMU.
> >
> > The problem would happen if you enable some sort of early framebuffer
> > support, such as simple-drm or simple-framebuffer. Maybe even efifb. I
> > think it'd still be worth getting the iommu-addresses code into r35 if
> > for nothing else but to have a bit more of a safety buffer for the
> > future.
> >
> > If we don't and for some reason decide that we want early framebuffer
> > support, it might be too late to get UEFI updated for Tegra194. I recall
> > that the UEFI code for Tegra194 is different from the one for Tegra234,
> > so it is probably not as trivial as a simple cherry-pick, but I'll try
> > to do some digging and find the code that does this for Xavier.
> 
> Any updates on this?

FWIW, in my testing with L4T versions with UEFI firmware, I'm not seeing 
any issues even if efifb is enabled. My inclination would be to merge, 
and we can work on issues related to early framebuffer separately.

Outside adding support to r35, one option is to make it so TegraDRM has 
to explicitly call tegra_mc_probe_device (not necessarily directly) when 
it has quiesced the hardware during probe. This would not allow seamless 
early framebuffer transition, but otherwise it should work. Implementing 
this for tegra-smmu would also allow us to get rid of the IOMMU API 
paths in TegraDRM and Host1x, which would be a great boon.

Cheers
Mikko

> 
> Aaron





^ permalink raw reply

* Re: [PATCH ath-next v4 0/6] wifi: ath12k: Enable IPQ5424 AHB WiFi device
From: Raj Kumar Bhagat @ 2026-04-07  4:09 UTC (permalink / raw)
  To: Baochen Qiang, Krzysztof Kozlowski, Johannes Berg, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Saravanakumar Duraisamy, Sowmiya Sree Elavalagan
In-Reply-To: <09fb6efd-646b-4d0d-a0f3-9f6ce4b38442@oss.qualcomm.com>

On 07-04-2026 07:53, Baochen Qiang wrote:
> 
> 
> On 4/4/2026 1:23 PM, Krzysztof Kozlowski wrote:
>> On 03/04/2026 11:13, Baochen Qiang wrote:
>>>>
>>>>   .../bindings/net/wireless/qcom,ipq5332-wifi.yaml   |  1 +
>>>>   drivers/net/wireless/ath/ath12k/ahb.c              | 36 +++++----
>>>>   drivers/net/wireless/ath/ath12k/ahb.h              |  1 +
>>>>   drivers/net/wireless/ath/ath12k/ce.h               | 13 ++-
>>>>   drivers/net/wireless/ath/ath12k/core.h             |  1 +
>>>>   drivers/net/wireless/ath/ath12k/wifi7/ahb.c        |  8 ++
>>>>   drivers/net/wireless/ath/ath12k/wifi7/hal.c        |  7 ++
>>>>   drivers/net/wireless/ath/ath12k/wifi7/hal.h        |  3 +
>>>>   .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.c    | 88 ++++++++++++++++++++
>>>>   .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.h    |  1 +
>>>>   drivers/net/wireless/ath/ath12k/wifi7/hw.c         | 93 +++++++++++++++++++++-
>>>>   11 files changed, 231 insertions(+), 21 deletions(-)
>>>> ---
>>>> base-commit: 15551ababf6d4e857f2101366a0c3eaa86dd822c
>>>> change-id: 20260331-ath12k-ipq5424-cddb63a46a97
>>>>
>>>
>>> only nit in patch 2/6, so for patches 2-6/6:
>>>
>>> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
>>
>> It does not work like this. Replying to cover letter causes that all
>> patches will get it. Provide detailed review and response to each email
>> in such case.
> 
> Got it, thank you!

will address the nit in patch 2/6.
As intended in next version, will have your Reviewed-by tag for patches
2-6/6.

^ permalink raw reply

* Re: [PATCH ath-next v4 2/6] wifi: ath12k: Add ath12k_hw_params for IPQ5424
From: Raj Kumar Bhagat @ 2026-04-07  4:06 UTC (permalink / raw)
  To: Baochen Qiang, Johannes Berg, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jeff Johnson
  Cc: linux-wireless, devicetree, linux-kernel, ath12k,
	Saravanakumar Duraisamy
In-Reply-To: <5fff7189-fee7-4d73-a9a1-728389900678@oss.qualcomm.com>

On 03-04-2026 14:31, Baochen Qiang wrote:
>> +	{
>> +		.name = "ipq5424 hw1.0",
>> +		.hw_rev = ATH12K_HW_IPQ5424_HW10,
>> +		.fw = {
>> +			.dir = "IPQ5424/hw1.0",
>> +			.board_size = 256 * 1024,
>> +			.cal_offset = 128 * 1024,
>> +			.m3_loader = ath12k_m3_fw_loader_remoteproc,
>> +			.download_aux_ucode = false,
>> +		},
>> +		.max_radios = 1,
>> +		.single_pdev_only = false,
>> +		.qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332,
>> +		.internal_sleep_clock = false,
>> +
>> +		.hw_ops = &qcn9274_ops,
>> +		.ring_mask = &ath12k_wifi7_hw_ring_mask_ipq5332,
>> +
>> +		.host_ce_config = ath12k_wifi7_host_ce_config_ipq5332,
>> +		.ce_count = 12,
>> +		.target_ce_config = ath12k_wifi7_target_ce_config_wlan_ipq5332,
>> +		.target_ce_count = 12,
>> +		.svc_to_ce_map =
>> +			ath12k_wifi7_target_service_to_ce_map_wlan_ipq5332,
>> +		.svc_to_ce_map_len = 18,
>> +
>> +		.rxdma1_enable = true,
>> +		.num_rxdma_per_pdev = 1,
>> +		.num_rxdma_dst_ring = 0,
>> +		.rx_mac_buf_ring = false,
>> +		.vdev_start_delay = false,
>> +
>> +		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
>> +				   BIT(NL80211_IFTYPE_AP) |
>> +				   BIT(NL80211_IFTYPE_MESH_POINT),
>> +		.supports_monitor = true,
>> +
>> +		.idle_ps = false,
>> +		.download_calib = true,
>> +		.supports_suspend = false,
>> +		.tcl_ring_retry = true,
>> +		.reoq_lut_support = false,
>> +		.supports_shadow_regs = false,
>> +
>> +		.num_tcl_banks = 48,
>> +		.max_tx_ring = 4,
>> +
>> +		.wmi_init = &ath12k_wifi7_wmi_init_qcn9274,
>> +
>> +		.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
>> +
>> +		.rfkill_pin = 0,
>> +		.rfkill_cfg = 0,
>> +		.rfkill_on_level = 0,
>> +
>> +		.rddm_size = 0,
>> +
>> +		.def_num_link = 0,
>> +		.max_mlo_peer = 256,
>> +
>> +		.otp_board_id_register = 0,
>> +
>> +		.supports_sta_ps = false,
>> +
>> +		.acpi_guid = NULL,
>> +		.supports_dynamic_smps_6ghz = false,
>> +		.iova_mask = 0,
>> +		.supports_aspm = false,
>> +
>> +		.ce_ie_addr = NULL,
>> +		.ce_remap = NULL,
>> +		.bdf_addr_offset = 0x940000,
>> +
>> +		.dp_primary_link_only = true,
>> +	},
>>   };
> mhi_config and current_cc_support are missing, please explicitly set them.

Sure will update in next version.

^ permalink raw reply

* [PATCH v5 2/2] iio: dac: ad5706r: Add support for AD5706R DAC
From: Alexis Czezar Torreno @ 2026-04-07  3:39 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-iio, devicetree, linux-kernel, Alexis Czezar Torreno
In-Reply-To: <20260407-dev_ad5706r-v5-0-a4c7737b6ae9@analog.com>

Add support for the Analog Devices AD5706R, a 4-channel 16-bit
current output digital-to-analog converter with SPI interface.

Features:
  - 4 independent DAC channels
  - Hardware and software LDAC trigger
  - Configurable output range
  - PWM-based LDAC control
  - Dither and toggle modes
  - Dynamically configurable SPI speed

Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>

---
Changes in v5:
  - Kconfig: Added select REGMAP_SPI dependency
  - Headers: Removed device.h, errno.h, string.h; added dev_printk.h
  - Use IIO_DMA_MINALIGN instead of ARCH_DMA_MINALIGN
  - Replaced memcpy/memset with put_unaligned_be* for consistency
  - Added struct device *dev shorthand in probe()
  - Added newline to error message
  - Other minor style edits

Changes in v4:
  - Added missing includes
  - Converted to use regmap with custom SPI bus implementation
  - Removed driver-specific mutex/guards in favor of regmap locking
  - Minor style cleanups

Changes in v3:
  - Removed redundant includes, added respective includes of APIs used
  - Simplified bit manipulation in SPI read/write
  - Fixed inconsistent trailing commas in device ID tables
  - Removed zero initialization in spi_device_id

Changes in v2:
  - Removed PWM, GPIO, clock generator, debugfs, regmap, IIO_BUFFER
  - Removed all custom ext_info sysfs attributes
  - Simplified to basic raw read/write and read-only scale
  - SPI read/write can handle multibyte registers
---
---
 MAINTAINERS               |   1 +
 drivers/iio/dac/Kconfig   |  11 +++
 drivers/iio/dac/Makefile  |   1 +
 drivers/iio/dac/ad5706r.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 260 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 17a3d2d45fccb9cd3c93fd35666fb85d17d53cde..3d7bd98b4d1b55836e40687a9a3ac9f4935a8acb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1502,6 +1502,7 @@ L:	linux-iio@vger.kernel.org
 S:	Supported
 W:	https://ez.analog.com/linux-software-drivers
 F:	Documentation/devicetree/bindings/iio/dac/adi,ad5706r.yaml
+F:	drivers/iio/dac/ad5706r.c
 
 ANALOG DEVICES INC AD7091R DRIVER
 M:	Marcelo Schmitt <marcelo.schmitt@analog.com>
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index db9f5c711b3df90641f017652fbbef594cc1627d..a5a328818233e3d019cddaee369dd5b7b1529031 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -178,6 +178,17 @@ config AD5624R_SPI
 	  Say yes here to build support for Analog Devices AD5624R, AD5644R and
 	  AD5664R converters (DAC). This driver uses the common SPI interface.
 
+config AD5706R
+	tristate "Analog Devices AD5706R DAC driver"
+	depends on SPI
+	select REGMAP_SPI
+	help
+	  Say yes here to build support for Analog Devices AD5706R 4-channel,
+	  16-bit current output DAC.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad5706r.
+
 config AD9739A
 	tristate "Analog Devices AD9739A RF DAC spi driver"
 	depends on SPI
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index 2a80bbf4e80ad557da79ed916027cedff286984b..0034317984985035f7987a744899924bfd4612e3 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_AD5449) += ad5449.o
 obj-$(CONFIG_AD5592R_BASE) += ad5592r-base.o
 obj-$(CONFIG_AD5592R) += ad5592r.o
 obj-$(CONFIG_AD5593R) += ad5593r.o
+obj-$(CONFIG_AD5706R) += ad5706r.o
 obj-$(CONFIG_AD5755) += ad5755.o
 obj-$(CONFIG_AD5758) += ad5758.o
 obj-$(CONFIG_AD5761) += ad5761.o
diff --git a/drivers/iio/dac/ad5706r.c b/drivers/iio/dac/ad5706r.c
new file mode 100644
index 0000000000000000000000000000000000000000..e868f25340855c5b2b54180420894372ba155116
--- /dev/null
+++ b/drivers/iio/dac/ad5706r.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AD5706R 16-bit Current Output Digital to Analog Converter
+ *
+ * Copyright 2026 Analog Devices Inc.
+ */
+
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/minmax.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+#include <linux/unaligned.h>
+
+/* SPI frame layout */
+#define AD5706R_RD_MASK			BIT(15)
+#define AD5706R_ADDR_MASK		GENMASK(11, 0)
+
+/* Registers */
+#define AD5706R_REG_DAC_INPUT_A_CH(x)		(0x60 + ((x) * 2))
+#define AD5706R_REG_DAC_DATA_READBACK_CH(x)	(0x68 + ((x) * 2))
+
+#define AD5706R_DAC_RESOLUTION		16
+#define AD5706R_DAC_MAX_CODE		BIT(16)
+#define AD5706R_MULTIBYTE_REG_START	0x14
+#define AD5706R_MULTIBYTE_REG_END	0x71
+#define AD5706R_MAX_REG			0x77
+#define AD5706R_SINGLE_BYTE_LEN		1
+#define AD5706R_DOUBLE_BYTE_LEN		2
+
+struct ad5706r_state {
+	struct spi_device *spi;
+	struct regmap *regmap;
+
+	u8 tx_buf[4] __aligned(IIO_DMA_MINALIGN);
+	u8 rx_buf[4];
+};
+
+static int ad5706r_reg_len(unsigned int reg)
+{
+	if (reg >= AD5706R_MULTIBYTE_REG_START && reg <= AD5706R_MULTIBYTE_REG_END)
+		return AD5706R_DOUBLE_BYTE_LEN;
+
+	return AD5706R_SINGLE_BYTE_LEN;
+}
+
+static int ad5706r_regmap_write(void *context, const void *data, size_t count)
+{
+	struct ad5706r_state *st = context;
+	unsigned int num_bytes, val;
+	u16 reg;
+
+	reg = get_unaligned_be16(data);
+	num_bytes = ad5706r_reg_len(reg);
+
+	struct spi_transfer xfer = {
+		.tx_buf = st->tx_buf,
+		.len = num_bytes + 2,
+	};
+
+	val = get_unaligned_be32(data);
+	put_unaligned_be32(val, st->tx_buf);
+
+	/* For single byte, copy the data to the correct position */
+	if (num_bytes == AD5706R_SINGLE_BYTE_LEN)
+		st->tx_buf[2] = st->tx_buf[3];
+
+	return spi_sync_transfer(st->spi, &xfer, 1);
+}
+
+static int ad5706r_regmap_read(void *context, const void *reg_buf,
+			       size_t reg_size, void *val_buf, size_t val_size)
+{
+	struct ad5706r_state *st = context;
+	unsigned int num_bytes;
+	u16 reg, cmd, val;
+	int ret;
+
+	reg = get_unaligned_be16(reg_buf);
+	num_bytes = ad5706r_reg_len(reg);
+
+	/* Full duplex, device responds immediately after command */
+	struct spi_transfer xfer = {
+		.tx_buf = st->tx_buf,
+		.rx_buf = st->rx_buf,
+		.len = 2 + num_bytes,
+	};
+
+	cmd = AD5706R_RD_MASK | (reg & AD5706R_ADDR_MASK);
+	put_unaligned_be16(cmd, st->tx_buf);
+	put_unaligned_be16(0, &st->tx_buf[2]);
+
+	ret = spi_sync_transfer(st->spi, &xfer, 1);
+	if (ret)
+		return ret;
+
+	/* Extract value from response (skip 2-byte command echo) */
+	if (num_bytes == AD5706R_SINGLE_BYTE_LEN)
+		val = st->rx_buf[2];
+	else if (num_bytes == AD5706R_DOUBLE_BYTE_LEN)
+		val = get_unaligned_be16(&st->rx_buf[2]);
+	else
+		return -EINVAL;
+
+	put_unaligned_be16(val, val_buf);
+
+	return 0;
+}
+
+static int ad5706r_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val, int *val2, long mask)
+{
+	struct ad5706r_state *st = iio_priv(indio_dev);
+	unsigned int reg, reg_val;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		reg = AD5706R_REG_DAC_DATA_READBACK_CH(chan->channel);
+		ret = regmap_read(st->regmap, reg, &reg_val);
+		if (ret)
+			return ret;
+
+		*val = reg_val;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 50;
+		*val2 = AD5706R_DAC_RESOLUTION;
+		return IIO_VAL_FRACTIONAL_LOG2;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ad5706r_write_raw(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     int val, int val2, long mask)
+{
+	struct ad5706r_state *st = iio_priv(indio_dev);
+	unsigned int reg;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (!in_range(val, 0, AD5706R_DAC_MAX_CODE))
+			return -EINVAL;
+
+		reg = AD5706R_REG_DAC_INPUT_A_CH(chan->channel);
+		return regmap_write(st->regmap, reg, val);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct regmap_bus ad5706r_regmap_bus = {
+	.write = ad5706r_regmap_write,
+	.read = ad5706r_regmap_read,
+	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
+	.val_format_endian_default = REGMAP_ENDIAN_BIG,
+};
+
+static const struct regmap_config ad5706r_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 16,
+	.max_register = AD5706R_MAX_REG,
+};
+
+static const struct iio_info ad5706r_info = {
+	.read_raw = ad5706r_read_raw,
+	.write_raw = ad5706r_write_raw,
+};
+
+#define AD5706R_CHAN(_channel) {				\
+	.type = IIO_CURRENT,					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
+			      BIT(IIO_CHAN_INFO_SCALE),	\
+	.output = 1,						\
+	.indexed = 1,						\
+	.channel = _channel,					\
+}
+
+static const struct iio_chan_spec ad5706r_channels[] = {
+	AD5706R_CHAN(0),
+	AD5706R_CHAN(1),
+	AD5706R_CHAN(2),
+	AD5706R_CHAN(3),
+};
+
+static int ad5706r_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct iio_dev *indio_dev;
+	struct ad5706r_state *st;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
+	st->spi = spi;
+
+	st->regmap = devm_regmap_init(dev, &ad5706r_regmap_bus,
+				      st, &ad5706r_regmap_config);
+	if (IS_ERR(st->regmap))
+		return dev_err_probe(dev, PTR_ERR(st->regmap),
+				     "Failed to init regmap\n");
+
+	indio_dev->name = "ad5706r";
+	indio_dev->info = &ad5706r_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = ad5706r_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad5706r_channels);
+
+	return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct of_device_id ad5706r_of_match[] = {
+	{ .compatible = "adi,ad5706r" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ad5706r_of_match);
+
+static const struct spi_device_id ad5706r_id[] = {
+	{ "ad5706r" },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, ad5706r_id);
+
+static struct spi_driver ad5706r_driver = {
+	.driver = {
+		.name = "ad5706r",
+		.of_match_table = ad5706r_of_match,
+	},
+	.probe = ad5706r_probe,
+	.id_table = ad5706r_id,
+};
+module_spi_driver(ad5706r_driver);
+
+MODULE_AUTHOR("Alexis Czezar Torreno <alexisczezar.torreno@analog.com>");
+MODULE_DESCRIPTION("AD5706R 16-bit Current Output DAC driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 1/2] dt-bindings: iio: dac: Add ADI AD5706R
From: Alexis Czezar Torreno @ 2026-04-07  3:39 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-iio, devicetree, linux-kernel, Alexis Czezar Torreno
In-Reply-To: <20260407-dev_ad5706r-v5-0-a4c7737b6ae9@analog.com>

Add device tree binding documentation for the Analog Devices
AD5706R 4-channel 16-bit current output digital-to-analog converter.

Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>

---
Changes in v5:
  - Changed out-en-gpios to enable-gpios.

Changes in v4:
  - Reverted pwm and gpio entries
  - Added missing power supply properties
  - Clocks not added back as they were driver specific

Changes in v3:
  - Added allOf and ref to spi-peripheral-props.yaml
  - Changed additionalProperties to unevaluatedProperties
  - Added avdd-supply property and added it to required

Changes in v1:
  - Removed clocks, clock-names, pwms, pwm-names, gpio properties
  - Simplified example to use plain SPI bus
---
---
 .../devicetree/bindings/iio/dac/adi,ad5706r.yaml   | 105 +++++++++++++++++++++
 MAINTAINERS                                        |   7 ++
 2 files changed, 112 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad5706r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad5706r.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..19cc744a9f0fc35907de8b8bdd9f088676620b54
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5706r.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/dac/adi,ad5706r.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices AD5706R 4-Channel Current Output DAC
+
+maintainers:
+  - Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
+
+description: |
+  The AD5706R is a 4-channel, 16-bit resolution, current output
+  digital-to-analog converter (DAC) with programmable output current
+  ranges (50mA, 150mA, 200mA, 300mA), an integrated 2.5V voltage
+  reference, and load DAC, A/B toggle, and dither functions.
+
+  Datasheet:
+    https://www.analog.com/en/products/ad5706r.html
+
+properties:
+  compatible:
+    enum:
+      - adi,ad5706r
+
+  reg:
+    maxItems: 1
+
+  avdd-supply:
+    description: Analog power supply (2.9V to 3.6V).
+
+  iovdd-supply:
+    description: Logic power supply (1.14V to 1.89V).
+
+  pvdd0-supply:
+    description: Power supply for IDAC0 channel (1.65V to AVDD).
+
+  pvdd1-supply:
+    description: Power supply for IDAC1 channel (1.65V to AVDD).
+
+  pvdd2-supply:
+    description: Power supply for IDAC2 channel (1.65V to AVDD).
+
+  pvdd3-supply:
+    description: Power supply for IDAC3 channel (1.65V to AVDD).
+
+  vref-supply:
+    description:
+      Optional external 2.5V voltage reference. If not provided, the
+      internal 2.5V reference is used.
+
+  pwms:
+    maxItems: 1
+    description:
+      Optional PWM connected to the LDAC/TGP/DCK pin for hardware
+      triggered DAC updates, toggle, or dither clock generation.
+
+  reset-gpios:
+    maxItems: 1
+    description:
+      GPIO connected to the active low RESET pin. If not provided,
+      software reset is used.
+
+  enable-gpios:
+    maxItems: 1
+    description:
+      GPIO connected to the active low OUT_EN pin. Controls whether
+      the current outputs are enabled or in high-Z/ground state.
+
+required:
+  - compatible
+  - reg
+  - avdd-supply
+  - iovdd-supply
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        dac@0 {
+            compatible = "adi,ad5706r";
+            reg = <0>;
+            avdd-supply = <&avdd>;
+            iovdd-supply = <&iovdd>;
+            pvdd0-supply = <&pvdd>;
+            pvdd1-supply = <&pvdd>;
+            pvdd2-supply = <&pvdd>;
+            pvdd3-supply = <&pvdd>;
+            vref-supply = <&vref>;
+            spi-max-frequency = <50000000>;
+            pwms = <&pwm0 0 1000000 0>;
+            reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+            enable-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 1251965d70bdfa990c66966cd77f7ab52ae3385f..17a3d2d45fccb9cd3c93fd35666fb85d17d53cde 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1496,6 +1496,13 @@ W:	https://ez.analog.com/linux-software-drivers
 F:	Documentation/devicetree/bindings/iio/adc/adi,ad4851.yaml
 F:	drivers/iio/adc/ad4851.c
 
+ANALOG DEVICES INC AD5706R DRIVER
+M:	Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
+L:	linux-iio@vger.kernel.org
+S:	Supported
+W:	https://ez.analog.com/linux-software-drivers
+F:	Documentation/devicetree/bindings/iio/dac/adi,ad5706r.yaml
+
 ANALOG DEVICES INC AD7091R DRIVER
 M:	Marcelo Schmitt <marcelo.schmitt@analog.com>
 L:	linux-iio@vger.kernel.org

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 0/2] Add support for AD5706R DAC
From: Alexis Czezar Torreno @ 2026-04-07  3:39 UTC (permalink / raw)
  To: Lars-Peter Clausen, Michael Hennerich, Jonathan Cameron,
	David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-iio, devicetree, linux-kernel, Alexis Czezar Torreno

This series adds support for the Analog Devices AD5706R, a 4-channel
16-bit current output digital-to-analog converter with SPI interface.

The AD5706R features:
  - 4 independent current output DAC channels
  - Configurable output ranges (50mA, 150mA, 200mA, 300mA)
  - Hardware and software LDAC trigger with configurable edge selection
  - Toggle and dither modes per channel
  - Internal or external voltage reference selection
  - PWM-controlled LDAC
  - Dynamic change SPI speed

The driver exposes standard IIO raw/scale/offset channel attributes for
DAC output control, sampling frequency for PWM-based LDAC timing, and
extended attributes for device configuration including output range
selection, trigger mode, and multiplexer output.

This driver is developed and tested on the Cora Z7S platform using
the AXI SPI Engine and AXI CLKGEN IP cores. The 'clocks' property
enables dynamic SPI clock rate management via the CLKGEN.

Datasheet: https://www.analog.com/en/products/ad5706r.html

Signed-off-by: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
---
Changes in v5:
- dt-bindings:
  - Changed out-en-gpios to enable-gpios
- driver:
  - Kconfig: Added select REGMAP_SPI
  - Headers: Removed device.h, errno.h, string.h; added dev_printk.h
  - Use IIO_DMA_MINALIGN instead of ARCH_DMA_MINALIGN
  - Replaced memcpy/memset with put_unaligned_be* for consistency
  - Added struct device *dev shorthand in probe()
  - other minor style edits
- Link to v4: https://lore.kernel.org/r/20260401-dev_ad5706r-v4-0-a785184a8d53@analog.com

Changes in v4:
- dt-bindings:
  - Reverted pwm and gpio entries.
  - Added missing power supply properties
  - Clocks not added back as they were driver specific, not device
    properties
- driver:
  - Added missing includes
  - Converted to use regmap with custom SPI bus implementation.
    spi_write_then_read not applied as suggested, prevents future
    need to change SPI speed
  - removed driver speciifc mutex/guards in favor of regmap internal
    locking
  - Minor style cleanups
- Link to v3: https://lore.kernel.org/r/20260318-dev_ad5706r-v3-0-5d078f41e988@analog.com

Changes in v3:
- Added MAINTAINERS entry, files added on each patch
- dt-bindings:
  - Added allOf and ref to spi-peripheral-props.yaml
  - Changed additionalProperties to unevaluatedProperties
  - Added avdd-supply property and added it to required
- driver:
  - Removed redundant includes, added respective includes of APIs used
  - Simplified bit manipulation in SPI read/write, used feedback from v2
  - Fixed inconsistent trailing commas in device ID tables
  - Removed zero initialization in spi_device_id
- Link to v2: https://lore.kernel.org/r/20260311-dev_ad5706r-v2-0-f367063dbd1b@analog.com

Changes in v2:
- Stripped driver down to basic DAC functionality (read/write raw,
  read-only scale) as suggested.
- Removed PWM (LDAC), GPIO (reset/shutdown), clock generator,
  SPI engine frequency switching, debugfs streaming, and all
  custom ext_info sysfs attributes
- Removed regmap, IIO_BUFFER, and iio/sysfs.h dependencies
- Simplified SPI read/write to use standard spi_sync_transfer
  without clock mode logic
- Scale reports default 50mA range as read-only using
  IIO_VAL_FRACTIONAL_LOG2; writable range selection deferred
  to future follow-up series
- Simplified DT binding to only require compatible, reg, and
  spi-max-frequency
- Link to v1: https://lore.kernel.org/r/20260220-dev_ad5706r-v1-0-7253bbd74889@analog.com

---
Alexis Czezar Torreno (2):
      dt-bindings: iio: dac: Add ADI AD5706R
      iio: dac: ad5706r: Add support for AD5706R DAC

 .../devicetree/bindings/iio/dac/adi,ad5706r.yaml   | 105 +++++++++
 MAINTAINERS                                        |   8 +
 drivers/iio/dac/Kconfig                            |  11 +
 drivers/iio/dac/Makefile                           |   1 +
 drivers/iio/dac/ad5706r.c                          | 247 +++++++++++++++++++++
 5 files changed, 372 insertions(+)
---
base-commit: 3674f3ca92730d9a07b42b311f1337d83c4d5605
change-id: 20260220-dev_ad5706r-2105e1dd29ab

Best regards,
-- 
Alexis Czezar Torreno <alexisczezar.torreno@analog.com>


^ permalink raw reply

* Re: [PATCH v4 2/3] ath10k: Add device-tree quirk to skip host cap QMI requests
From: Baochen Qiang @ 2026-04-07  3:36 UTC (permalink / raw)
  To: david, Johannes Berg, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jeff Johnson, Bjorn Andersson, Konrad Dybcio,
	Paul Sajna
  Cc: Amit Pundir, linux-wireless, devicetree, ath10k, linux-kernel,
	linux-arm-msm, phone-devel
In-Reply-To: <20260325-skip-host-cam-qmi-req-v4-2-bc08538487aa@ixit.cz>



On 3/26/2026 1:57 AM, David Heidelberg via B4 Relay wrote:
> From: Amit Pundir <amit.pundir@linaro.org>
> 
> Some firmware versions do not support the host capability QMI request.
> Since this request occurs before firmware-N.bin and board-M.bin are
> loaded, the quirk cannot be expressed in the firmware itself.
> 
> The root cause is unclear, but there appears to be a generation of
> firmware that lacks host capability support.
> 
> Without this quirk, ath10k_qmi_host_cap_send_sync() returns
> QMI_ERR_MALFORMED_MSG_V01 before loading the firmware. This error is not
> fatal - Wi-Fi services still come up successfully if the request is simply
> skipped.
> 
> Add a device-tree quirk to skip the host capability QMI request on devices
> whose firmware does not support it.
> 
> For example, firmware build
> "QC_IMAGE_VERSION_STRING=WLAN.HL.2.0.c3-00257-QCAHLSWMTPLZ-1"
> on Xiaomi Poco F1 phone requires this quirk.
> 
> Suggested-by: Bjorn Andersson <andersson@kernel.org>
> Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
>  drivers/net/wireless/ath/ath10k/qmi.c  | 13 ++++++++++---
>  drivers/net/wireless/ath/ath10k/snoc.c |  3 +++
>  drivers/net/wireless/ath/ath10k/snoc.h |  1 +
>  3 files changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c
> index eebd78e7ff6bc..e7f90fd9e9b83 100644
> --- a/drivers/net/wireless/ath/ath10k/qmi.c
> +++ b/drivers/net/wireless/ath/ath10k/qmi.c
> @@ -808,6 +808,7 @@ ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi)
>  static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi)
>  {
>  	struct ath10k *ar = qmi->ar;
> +	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
>  	int ret;
>  
>  	ret = ath10k_qmi_ind_register_send_sync_msg(qmi);
> @@ -819,9 +820,15 @@ static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi)
>  		return;
>  	}
>  
> -	ret = ath10k_qmi_host_cap_send_sync(qmi);
> -	if (ret)
> -		return;
> +	/*
> +	 * Skip the host capability request for the firmware versions which
> +	 * do not support this feature.
> +	 */
> +	if (!test_bit(ATH10K_SNOC_FLAG_SKIP_HOST_CAP_QUIRK, &ar_snoc->flags)) {
> +		ret = ath10k_qmi_host_cap_send_sync(qmi);
> +		if (ret)
> +			return;
> +	}
>  
>  	ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi);
>  	if (ret)
> diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
> index f72f236fb9eb3..3106502275781 100644
> --- a/drivers/net/wireless/ath/ath10k/snoc.c
> +++ b/drivers/net/wireless/ath/ath10k/snoc.c
> @@ -1362,6 +1362,9 @@ static void ath10k_snoc_quirks_init(struct ath10k *ar)
>  
>  	if (of_property_read_bool(dev->of_node, "qcom,snoc-host-cap-8bit-quirk"))
>  		set_bit(ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, &ar_snoc->flags);
> +
> +	if (of_property_read_bool(dev->of_node, "qcom,snoc-host-cap-skip-quirk"))
> +		set_bit(ATH10K_SNOC_FLAG_SKIP_HOST_CAP_QUIRK, &ar_snoc->flags);
>  }
>  
>  int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type)
> diff --git a/drivers/net/wireless/ath/ath10k/snoc.h b/drivers/net/wireless/ath/ath10k/snoc.h
> index 1ecae34687c21..46574fd8f84ee 100644
> --- a/drivers/net/wireless/ath/ath10k/snoc.h
> +++ b/drivers/net/wireless/ath/ath10k/snoc.h
> @@ -51,6 +51,7 @@ enum ath10k_snoc_flags {
>  	ATH10K_SNOC_FLAG_MODEM_STOPPED,
>  	ATH10K_SNOC_FLAG_RECOVERY,
>  	ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK,
> +	ATH10K_SNOC_FLAG_SKIP_HOST_CAP_QUIRK,
>  };
>  
>  struct clk_bulk_data;
> 

Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH 1/2] riscv: dts: sophgo: sg2044: use hex for CPU unit address
From: Inochi Amaoto @ 2026-04-07  3:35 UTC (permalink / raw)
  To: Guo Ren, Inochi Amaoto
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Chen Wang, Han Gao,
	Nutty Liu, Guodong Xu, Xiaoguang Xing, devicetree, linux-riscv,
	sophgo, linux-kernel, Yixun Lan, Longbin Li
In-Reply-To: <CAJF2gTRvvVLg1O6ZA_Lo7tsmN_EXeZaDNrW1M9JFHDwZN2iYGg@mail.gmail.com>

On Tue, Apr 07, 2026 at 11:08:19AM +0800, Guo Ren wrote:
> On Tue, Apr 7, 2026 at 10:37 AM Inochi Amaoto <inochiama@gmail.com> wrote:
> >
> > On Tue, Apr 07, 2026 at 09:26:11AM +0800, Guo Ren wrote:
> > > On Tue, Apr 7, 2026 at 7:27 AM Inochi Amaoto <inochiama@gmail.com> wrote:
> > > >
> > > > Previous the CPU unit address cpu of sg2044 use decimal, it is
> > > > not following the general convention for unit addresses of the
> > > > OF. Convent the unit address to hex to resolve this problem.
> > > >
> > > > The introduces a small ABI break for the CPU id, but it should
> > > > affect nothing since there is no direct full-path reference to
> > > > these CPU nodes.
> > > >
> > > > Fixes: 967a94a92aaa ("riscv: dts: add initial Sophgo SG2042 SoC device tree")
> > > > Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
> > > > Link: https://lore.kernel.org/devicetree-spec/00ddad5a-02f5-474e-af9c-11ce7716ddfc@iscas.ac.cn/
> > >
> > > Remove the Link tag, and add:
> > >
> > > Reviewed-by: Guo Ren <guoren@kernel.org>
> > >
> >
> > This link provides the motivation for this patch, I think it will be
> > fine for other to know why this patch is needed.
> 
> The commit log already clearly describes the motivation:
>  - why we need to change from decimal to hex (OF unit address convention),
>  - the small ABI impact,
>  - and the Fixes tag.
> 
> Adding a Link: tag that points back to the discussion thread doesn't
> provide any additional information beyond what's already in the commit
> message. In my opinion, the commit log is sufficient and
> self-contained.
> 
> Linus recently made it very clear that he wants us to stop adding
> these kinds of low-value Link tags, as they just waste reviewers'
> time:
> 
> https://www.phoronix.com/news/Linus-Torvalds-No-Link-Tags
> 
> 

Thanks for your detailed explanation. In this case the Link is indeed
not valuable. I will remove it. Thanks.

> >
> > Regards,
> > Inochi
> >
> > > > ---
> > > >  arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi | 236 ++++++++++----------
> > > >  1 file changed, 118 insertions(+), 118 deletions(-)
> > > >
> > > > diff --git a/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi b/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi
> > > > index 3135409c2149..f66a382c95bd 100644
> > > > --- a/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi
> > > > +++ b/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi
> > > > @@ -14,7 +14,7 @@ cpus {
> > > >
> > > >                 cpu0: cpu@0 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <0>;
> > > > +                       reg = <0x0>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -50,7 +50,7 @@ cpu0_intc: interrupt-controller {
> > > >
> > > >                 cpu1: cpu@1 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <1>;
> > > > +                       reg = <0x1>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -86,7 +86,7 @@ cpu1_intc: interrupt-controller {
> > > >
> > > >                 cpu2: cpu@2 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <2>;
> > > > +                       reg = <0x2>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -122,7 +122,7 @@ cpu2_intc: interrupt-controller {
> > > >
> > > >                 cpu3: cpu@3 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <3>;
> > > > +                       reg = <0x3>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -158,7 +158,7 @@ cpu3_intc: interrupt-controller {
> > > >
> > > >                 cpu4: cpu@4 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <4>;
> > > > +                       reg = <0x4>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -194,7 +194,7 @@ cpu4_intc: interrupt-controller {
> > > >
> > > >                 cpu5: cpu@5 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <5>;
> > > > +                       reg = <0x5>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -230,7 +230,7 @@ cpu5_intc: interrupt-controller {
> > > >
> > > >                 cpu6: cpu@6 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <6>;
> > > > +                       reg = <0x6>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -266,7 +266,7 @@ cpu6_intc: interrupt-controller {
> > > >
> > > >                 cpu7: cpu@7 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <7>;
> > > > +                       reg = <0x7>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -302,7 +302,7 @@ cpu7_intc: interrupt-controller {
> > > >
> > > >                 cpu8: cpu@8 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <8>;
> > > > +                       reg = <0x8>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -338,7 +338,7 @@ cpu8_intc: interrupt-controller {
> > > >
> > > >                 cpu9: cpu@9 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <9>;
> > > > +                       reg = <0x9>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -372,9 +372,9 @@ cpu9_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu10: cpu@10 {
> > > > +               cpu10: cpu@a {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <10>;
> > > > +                       reg = <0xa>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -408,9 +408,9 @@ cpu10_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu11: cpu@11 {
> > > > +               cpu11: cpu@b {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <11>;
> > > > +                       reg = <0xb>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -444,9 +444,9 @@ cpu11_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu12: cpu@12 {
> > > > +               cpu12: cpu@c {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <12>;
> > > > +                       reg = <0xc>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -480,9 +480,9 @@ cpu12_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu13: cpu@13 {
> > > > +               cpu13: cpu@d {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <13>;
> > > > +                       reg = <0xd>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -516,9 +516,9 @@ cpu13_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu14: cpu@14 {
> > > > +               cpu14: cpu@e {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <14>;
> > > > +                       reg = <0xe>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -552,9 +552,9 @@ cpu14_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu15: cpu@15 {
> > > > +               cpu15: cpu@f {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <15>;
> > > > +                       reg = <0xf>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -588,9 +588,9 @@ cpu15_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu16: cpu@16 {
> > > > +               cpu16: cpu@10 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <16>;
> > > > +                       reg = <0x10>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -624,9 +624,9 @@ cpu16_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu17: cpu@17 {
> > > > +               cpu17: cpu@11 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <17>;
> > > > +                       reg = <0x11>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -660,9 +660,9 @@ cpu17_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu18: cpu@18 {
> > > > +               cpu18: cpu@12 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <18>;
> > > > +                       reg = <0x12>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -696,9 +696,9 @@ cpu18_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu19: cpu@19 {
> > > > +               cpu19: cpu@13 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <19>;
> > > > +                       reg = <0x13>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -732,9 +732,9 @@ cpu19_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu20: cpu@20 {
> > > > +               cpu20: cpu@14 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <20>;
> > > > +                       reg = <0x14>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -768,9 +768,9 @@ cpu20_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu21: cpu@21 {
> > > > +               cpu21: cpu@15 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <21>;
> > > > +                       reg = <0x15>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -804,9 +804,9 @@ cpu21_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu22: cpu@22 {
> > > > +               cpu22: cpu@16 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <22>;
> > > > +                       reg = <0x16>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -840,9 +840,9 @@ cpu22_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu23: cpu@23 {
> > > > +               cpu23: cpu@17 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <23>;
> > > > +                       reg = <0x17>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -876,9 +876,9 @@ cpu23_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu24: cpu@24 {
> > > > +               cpu24: cpu@18 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <24>;
> > > > +                       reg = <0x18>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -912,9 +912,9 @@ cpu24_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu25: cpu@25 {
> > > > +               cpu25: cpu@19 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <25>;
> > > > +                       reg = <0x19>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -948,9 +948,9 @@ cpu25_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu26: cpu@26 {
> > > > +               cpu26: cpu@1a {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <26>;
> > > > +                       reg = <0x1a>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -984,9 +984,9 @@ cpu26_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu27: cpu@27 {
> > > > +               cpu27: cpu@1b {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <27>;
> > > > +                       reg = <0x1b>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1020,9 +1020,9 @@ cpu27_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu28: cpu@28 {
> > > > +               cpu28: cpu@1c {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <28>;
> > > > +                       reg = <0x1c>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1056,9 +1056,9 @@ cpu28_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu29: cpu@29 {
> > > > +               cpu29: cpu@1d {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <29>;
> > > > +                       reg = <0x1d>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1092,9 +1092,9 @@ cpu29_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu30: cpu@30 {
> > > > +               cpu30: cpu@1e {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <30>;
> > > > +                       reg = <0x1e>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1128,9 +1128,9 @@ cpu30_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu31: cpu@31 {
> > > > +               cpu31: cpu@1f {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <31>;
> > > > +                       reg = <0x1f>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1164,9 +1164,9 @@ cpu31_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu32: cpu@32 {
> > > > +               cpu32: cpu@20 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <32>;
> > > > +                       reg = <0x20>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1200,9 +1200,9 @@ cpu32_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu33: cpu@33 {
> > > > +               cpu33: cpu@21 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <33>;
> > > > +                       reg = <0x21>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1236,9 +1236,9 @@ cpu33_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu34: cpu@34 {
> > > > +               cpu34: cpu@22 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <34>;
> > > > +                       reg = <0x22>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1272,9 +1272,9 @@ cpu34_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu35: cpu@35 {
> > > > +               cpu35: cpu@23 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <35>;
> > > > +                       reg = <0x23>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1308,9 +1308,9 @@ cpu35_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu36: cpu@36 {
> > > > +               cpu36: cpu@24 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <36>;
> > > > +                       reg = <0x24>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1344,9 +1344,9 @@ cpu36_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu37: cpu@37 {
> > > > +               cpu37: cpu@25 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <37>;
> > > > +                       reg = <0x25>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1380,9 +1380,9 @@ cpu37_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu38: cpu@38 {
> > > > +               cpu38: cpu@26 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <38>;
> > > > +                       reg = <0x26>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1416,9 +1416,9 @@ cpu38_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu39: cpu@39 {
> > > > +               cpu39: cpu@27 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <39>;
> > > > +                       reg = <0x27>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1452,9 +1452,9 @@ cpu39_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu40: cpu@40 {
> > > > +               cpu40: cpu@28 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <40>;
> > > > +                       reg = <0x28>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1488,9 +1488,9 @@ cpu40_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu41: cpu@41 {
> > > > +               cpu41: cpu@29 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <41>;
> > > > +                       reg = <0x29>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1524,9 +1524,9 @@ cpu41_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu42: cpu@42 {
> > > > +               cpu42: cpu@2a {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <42>;
> > > > +                       reg = <0x2a>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1560,9 +1560,9 @@ cpu42_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu43: cpu@43 {
> > > > +               cpu43: cpu@2b {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <43>;
> > > > +                       reg = <0x2b>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1596,9 +1596,9 @@ cpu43_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu44: cpu@44 {
> > > > +               cpu44: cpu@2c {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <44>;
> > > > +                       reg = <0x2c>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1632,9 +1632,9 @@ cpu44_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu45: cpu@45 {
> > > > +               cpu45: cpu@2d {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <45>;
> > > > +                       reg = <0x2d>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1668,9 +1668,9 @@ cpu45_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu46: cpu@46 {
> > > > +               cpu46: cpu@2e {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <46>;
> > > > +                       reg = <0x2e>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1704,9 +1704,9 @@ cpu46_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu47: cpu@47 {
> > > > +               cpu47: cpu@2f {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <47>;
> > > > +                       reg = <0x2f>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1740,9 +1740,9 @@ cpu47_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu48: cpu@48 {
> > > > +               cpu48: cpu@30 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <48>;
> > > > +                       reg = <0x30>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1776,9 +1776,9 @@ cpu48_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu49: cpu@49 {
> > > > +               cpu49: cpu@31 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <49>;
> > > > +                       reg = <0x31>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1812,9 +1812,9 @@ cpu49_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu50: cpu@50 {
> > > > +               cpu50: cpu@32 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <50>;
> > > > +                       reg = <0x32>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1848,9 +1848,9 @@ cpu50_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu51: cpu@51 {
> > > > +               cpu51: cpu@33 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <51>;
> > > > +                       reg = <0x33>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1884,9 +1884,9 @@ cpu51_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu52: cpu@52 {
> > > > +               cpu52: cpu@34 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <52>;
> > > > +                       reg = <0x34>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1920,9 +1920,9 @@ cpu52_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu53: cpu@53 {
> > > > +               cpu53: cpu@35 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <53>;
> > > > +                       reg = <0x35>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1956,9 +1956,9 @@ cpu53_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu54: cpu@54 {
> > > > +               cpu54: cpu@36 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <54>;
> > > > +                       reg = <0x36>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -1992,9 +1992,9 @@ cpu54_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu55: cpu@55 {
> > > > +               cpu55: cpu@37 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <55>;
> > > > +                       reg = <0x37>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2028,9 +2028,9 @@ cpu55_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu56: cpu@56 {
> > > > +               cpu56: cpu@38 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <56>;
> > > > +                       reg = <0x38>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2064,9 +2064,9 @@ cpu56_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu57: cpu@57 {
> > > > +               cpu57: cpu@39 {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <57>;
> > > > +                       reg = <0x39>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2100,9 +2100,9 @@ cpu57_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu58: cpu@58 {
> > > > +               cpu58: cpu@3a {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <58>;
> > > > +                       reg = <0x3a>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2136,9 +2136,9 @@ cpu58_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu59: cpu@59 {
> > > > +               cpu59: cpu@3b {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <59>;
> > > > +                       reg = <0x3b>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2172,9 +2172,9 @@ cpu59_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu60: cpu@60 {
> > > > +               cpu60: cpu@3c {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <60>;
> > > > +                       reg = <0x3c>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2208,9 +2208,9 @@ cpu60_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu61: cpu@61 {
> > > > +               cpu61: cpu@3d {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <61>;
> > > > +                       reg = <0x3d>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2244,9 +2244,9 @@ cpu61_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu62: cpu@62 {
> > > > +               cpu62: cpu@3e {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <62>;
> > > > +                       reg = <0x3e>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > @@ -2280,9 +2280,9 @@ cpu62_intc: interrupt-controller {
> > > >                         };
> > > >                 };
> > > >
> > > > -               cpu63: cpu@63 {
> > > > +               cpu63: cpu@3f {
> > > >                         compatible = "thead,c920", "riscv";
> > > > -                       reg = <63>;
> > > > +                       reg = <0x3f>;
> > > >                         i-cache-block-size = <64>;
> > > >                         i-cache-size = <65536>;
> > > >                         i-cache-sets = <512>;
> > > > --
> > > > 2.53.0
> > > >
> > >
> > >
> > > --
> > > Best Regards
> > >  Guo Ren
> 
> 
> 
> --
> Best Regards
>  Guo Ren

^ permalink raw reply

* RE: [PATCH V10 03/13] PCI: dwc: Parse Root Port nodes in dw_pcie_host_init()
From: Sherry Sun @ 2026-04-07  3:21 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	Frank Li, s.hauer@pengutronix.de, kernel@pengutronix.de,
	festevam@gmail.com, lpieralisi@kernel.org, kwilczynski@kernel.org,
	bhelgaas@google.com, Hongxing Zhu, l.stach@pengutronix.de,
	imx@lists.linux.dev, linux-pci@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <xlsfwtcy3wl6nasmx2w2oys6u4bbnvh24qiwr4pf3v5uz523gz@qvhzqfcs5q2c>

> On Thu, Apr 02, 2026 at 05:50:57PM +0800, Sherry Sun wrote:
> > Add support for parsing Root Port child nodes in dw_pcie_host_init()
> > using pci_host_common_parse_ports(). This allows DWC-based drivers to
> > specify Root Port properties (like reset GPIOs) in individual Root
> > Port nodes rather than in the host bridge node.
> >
> > Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
> > ---
> >  drivers/pci/controller/dwc/pcie-designware-host.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c
> > b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index da152c31bb2e..f6fca984fb34 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -20,6 +20,7 @@
> >  #include <linux/platform_device.h>
> >
> >  #include "../../pci.h"
> > +#include "../pci-host-common.h"
> >  #include "pcie-designware.h"
> >
> >  static struct pci_ops dw_pcie_ops;
> > @@ -581,6 +582,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> >
> >  	pp->bridge = bridge;
> >
> > +	/* Parse Root Port nodes if present */
> > +	ret = pci_host_common_parse_ports(dev, bridge);
> > +	if (ret && ret != -ENOENT) {
> > +		dev_err(dev, "Failed to parse Root Port nodes: %d\n", ret);
> > +		return ret;
> 
> Won't this change break drivers that parse Root Ports on their own? Either
> you need to modify them also in this change or call this API from imx6 driver
> and let other drivers switch to it in a phased manner.
> 
> I perfer the latter.

Hi Mani, sorry I didn't fully get your point here, there are no changes to this part
V10, for drivers that parse Root Ports on their own, here pci_host_common_parse_ports()
will return -ENOENT, so nothing break as we discussed this in V8
https://lore.kernel.org/all/dcl3bdljrdzgeaybrg3dc5uaxkebkjns7pajix6mxxftao5g4m@vm3ywyyp4ujh/.

Best Regards
Sherry



^ permalink raw reply

* Re: [PATCH 1/2] riscv: dts: sophgo: sg2044: use hex for CPU unit address
From: Guo Ren @ 2026-04-07  3:08 UTC (permalink / raw)
  To: Inochi Amaoto
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Chen Wang, Han Gao,
	Nutty Liu, Guodong Xu, Xiaoguang Xing, devicetree, linux-riscv,
	sophgo, linux-kernel, Yixun Lan, Longbin Li
In-Reply-To: <adRtlyqIupCqvkeD@inochi.infowork>

On Tue, Apr 7, 2026 at 10:37 AM Inochi Amaoto <inochiama@gmail.com> wrote:
>
> On Tue, Apr 07, 2026 at 09:26:11AM +0800, Guo Ren wrote:
> > On Tue, Apr 7, 2026 at 7:27 AM Inochi Amaoto <inochiama@gmail.com> wrote:
> > >
> > > Previous the CPU unit address cpu of sg2044 use decimal, it is
> > > not following the general convention for unit addresses of the
> > > OF. Convent the unit address to hex to resolve this problem.
> > >
> > > The introduces a small ABI break for the CPU id, but it should
> > > affect nothing since there is no direct full-path reference to
> > > these CPU nodes.
> > >
> > > Fixes: 967a94a92aaa ("riscv: dts: add initial Sophgo SG2042 SoC device tree")
> > > Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
> > > Link: https://lore.kernel.org/devicetree-spec/00ddad5a-02f5-474e-af9c-11ce7716ddfc@iscas.ac.cn/
> >
> > Remove the Link tag, and add:
> >
> > Reviewed-by: Guo Ren <guoren@kernel.org>
> >
>
> This link provides the motivation for this patch, I think it will be
> fine for other to know why this patch is needed.

The commit log already clearly describes the motivation:
 - why we need to change from decimal to hex (OF unit address convention),
 - the small ABI impact,
 - and the Fixes tag.

Adding a Link: tag that points back to the discussion thread doesn't
provide any additional information beyond what's already in the commit
message. In my opinion, the commit log is sufficient and
self-contained.

Linus recently made it very clear that he wants us to stop adding
these kinds of low-value Link tags, as they just waste reviewers'
time:

https://www.phoronix.com/news/Linus-Torvalds-No-Link-Tags


>
> Regards,
> Inochi
>
> > > ---
> > >  arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi | 236 ++++++++++----------
> > >  1 file changed, 118 insertions(+), 118 deletions(-)
> > >
> > > diff --git a/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi b/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi
> > > index 3135409c2149..f66a382c95bd 100644
> > > --- a/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi
> > > +++ b/arch/riscv/boot/dts/sophgo/sg2044-cpus.dtsi
> > > @@ -14,7 +14,7 @@ cpus {
> > >
> > >                 cpu0: cpu@0 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <0>;
> > > +                       reg = <0x0>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -50,7 +50,7 @@ cpu0_intc: interrupt-controller {
> > >
> > >                 cpu1: cpu@1 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <1>;
> > > +                       reg = <0x1>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -86,7 +86,7 @@ cpu1_intc: interrupt-controller {
> > >
> > >                 cpu2: cpu@2 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <2>;
> > > +                       reg = <0x2>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -122,7 +122,7 @@ cpu2_intc: interrupt-controller {
> > >
> > >                 cpu3: cpu@3 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <3>;
> > > +                       reg = <0x3>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -158,7 +158,7 @@ cpu3_intc: interrupt-controller {
> > >
> > >                 cpu4: cpu@4 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <4>;
> > > +                       reg = <0x4>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -194,7 +194,7 @@ cpu4_intc: interrupt-controller {
> > >
> > >                 cpu5: cpu@5 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <5>;
> > > +                       reg = <0x5>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -230,7 +230,7 @@ cpu5_intc: interrupt-controller {
> > >
> > >                 cpu6: cpu@6 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <6>;
> > > +                       reg = <0x6>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -266,7 +266,7 @@ cpu6_intc: interrupt-controller {
> > >
> > >                 cpu7: cpu@7 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <7>;
> > > +                       reg = <0x7>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -302,7 +302,7 @@ cpu7_intc: interrupt-controller {
> > >
> > >                 cpu8: cpu@8 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <8>;
> > > +                       reg = <0x8>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -338,7 +338,7 @@ cpu8_intc: interrupt-controller {
> > >
> > >                 cpu9: cpu@9 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <9>;
> > > +                       reg = <0x9>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -372,9 +372,9 @@ cpu9_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu10: cpu@10 {
> > > +               cpu10: cpu@a {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <10>;
> > > +                       reg = <0xa>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -408,9 +408,9 @@ cpu10_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu11: cpu@11 {
> > > +               cpu11: cpu@b {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <11>;
> > > +                       reg = <0xb>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -444,9 +444,9 @@ cpu11_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu12: cpu@12 {
> > > +               cpu12: cpu@c {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <12>;
> > > +                       reg = <0xc>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -480,9 +480,9 @@ cpu12_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu13: cpu@13 {
> > > +               cpu13: cpu@d {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <13>;
> > > +                       reg = <0xd>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -516,9 +516,9 @@ cpu13_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu14: cpu@14 {
> > > +               cpu14: cpu@e {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <14>;
> > > +                       reg = <0xe>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -552,9 +552,9 @@ cpu14_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu15: cpu@15 {
> > > +               cpu15: cpu@f {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <15>;
> > > +                       reg = <0xf>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -588,9 +588,9 @@ cpu15_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu16: cpu@16 {
> > > +               cpu16: cpu@10 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <16>;
> > > +                       reg = <0x10>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -624,9 +624,9 @@ cpu16_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu17: cpu@17 {
> > > +               cpu17: cpu@11 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <17>;
> > > +                       reg = <0x11>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -660,9 +660,9 @@ cpu17_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu18: cpu@18 {
> > > +               cpu18: cpu@12 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <18>;
> > > +                       reg = <0x12>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -696,9 +696,9 @@ cpu18_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu19: cpu@19 {
> > > +               cpu19: cpu@13 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <19>;
> > > +                       reg = <0x13>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -732,9 +732,9 @@ cpu19_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu20: cpu@20 {
> > > +               cpu20: cpu@14 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <20>;
> > > +                       reg = <0x14>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -768,9 +768,9 @@ cpu20_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu21: cpu@21 {
> > > +               cpu21: cpu@15 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <21>;
> > > +                       reg = <0x15>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -804,9 +804,9 @@ cpu21_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu22: cpu@22 {
> > > +               cpu22: cpu@16 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <22>;
> > > +                       reg = <0x16>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -840,9 +840,9 @@ cpu22_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu23: cpu@23 {
> > > +               cpu23: cpu@17 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <23>;
> > > +                       reg = <0x17>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -876,9 +876,9 @@ cpu23_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu24: cpu@24 {
> > > +               cpu24: cpu@18 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <24>;
> > > +                       reg = <0x18>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -912,9 +912,9 @@ cpu24_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu25: cpu@25 {
> > > +               cpu25: cpu@19 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <25>;
> > > +                       reg = <0x19>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -948,9 +948,9 @@ cpu25_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu26: cpu@26 {
> > > +               cpu26: cpu@1a {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <26>;
> > > +                       reg = <0x1a>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -984,9 +984,9 @@ cpu26_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu27: cpu@27 {
> > > +               cpu27: cpu@1b {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <27>;
> > > +                       reg = <0x1b>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1020,9 +1020,9 @@ cpu27_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu28: cpu@28 {
> > > +               cpu28: cpu@1c {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <28>;
> > > +                       reg = <0x1c>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1056,9 +1056,9 @@ cpu28_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu29: cpu@29 {
> > > +               cpu29: cpu@1d {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <29>;
> > > +                       reg = <0x1d>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1092,9 +1092,9 @@ cpu29_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu30: cpu@30 {
> > > +               cpu30: cpu@1e {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <30>;
> > > +                       reg = <0x1e>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1128,9 +1128,9 @@ cpu30_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu31: cpu@31 {
> > > +               cpu31: cpu@1f {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <31>;
> > > +                       reg = <0x1f>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1164,9 +1164,9 @@ cpu31_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu32: cpu@32 {
> > > +               cpu32: cpu@20 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <32>;
> > > +                       reg = <0x20>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1200,9 +1200,9 @@ cpu32_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu33: cpu@33 {
> > > +               cpu33: cpu@21 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <33>;
> > > +                       reg = <0x21>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1236,9 +1236,9 @@ cpu33_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu34: cpu@34 {
> > > +               cpu34: cpu@22 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <34>;
> > > +                       reg = <0x22>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1272,9 +1272,9 @@ cpu34_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu35: cpu@35 {
> > > +               cpu35: cpu@23 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <35>;
> > > +                       reg = <0x23>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1308,9 +1308,9 @@ cpu35_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu36: cpu@36 {
> > > +               cpu36: cpu@24 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <36>;
> > > +                       reg = <0x24>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1344,9 +1344,9 @@ cpu36_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu37: cpu@37 {
> > > +               cpu37: cpu@25 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <37>;
> > > +                       reg = <0x25>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1380,9 +1380,9 @@ cpu37_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu38: cpu@38 {
> > > +               cpu38: cpu@26 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <38>;
> > > +                       reg = <0x26>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1416,9 +1416,9 @@ cpu38_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu39: cpu@39 {
> > > +               cpu39: cpu@27 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <39>;
> > > +                       reg = <0x27>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1452,9 +1452,9 @@ cpu39_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu40: cpu@40 {
> > > +               cpu40: cpu@28 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <40>;
> > > +                       reg = <0x28>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1488,9 +1488,9 @@ cpu40_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu41: cpu@41 {
> > > +               cpu41: cpu@29 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <41>;
> > > +                       reg = <0x29>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1524,9 +1524,9 @@ cpu41_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu42: cpu@42 {
> > > +               cpu42: cpu@2a {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <42>;
> > > +                       reg = <0x2a>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1560,9 +1560,9 @@ cpu42_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu43: cpu@43 {
> > > +               cpu43: cpu@2b {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <43>;
> > > +                       reg = <0x2b>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1596,9 +1596,9 @@ cpu43_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu44: cpu@44 {
> > > +               cpu44: cpu@2c {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <44>;
> > > +                       reg = <0x2c>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1632,9 +1632,9 @@ cpu44_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu45: cpu@45 {
> > > +               cpu45: cpu@2d {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <45>;
> > > +                       reg = <0x2d>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1668,9 +1668,9 @@ cpu45_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu46: cpu@46 {
> > > +               cpu46: cpu@2e {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <46>;
> > > +                       reg = <0x2e>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1704,9 +1704,9 @@ cpu46_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu47: cpu@47 {
> > > +               cpu47: cpu@2f {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <47>;
> > > +                       reg = <0x2f>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1740,9 +1740,9 @@ cpu47_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu48: cpu@48 {
> > > +               cpu48: cpu@30 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <48>;
> > > +                       reg = <0x30>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1776,9 +1776,9 @@ cpu48_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu49: cpu@49 {
> > > +               cpu49: cpu@31 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <49>;
> > > +                       reg = <0x31>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1812,9 +1812,9 @@ cpu49_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu50: cpu@50 {
> > > +               cpu50: cpu@32 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <50>;
> > > +                       reg = <0x32>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1848,9 +1848,9 @@ cpu50_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu51: cpu@51 {
> > > +               cpu51: cpu@33 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <51>;
> > > +                       reg = <0x33>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1884,9 +1884,9 @@ cpu51_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu52: cpu@52 {
> > > +               cpu52: cpu@34 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <52>;
> > > +                       reg = <0x34>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1920,9 +1920,9 @@ cpu52_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu53: cpu@53 {
> > > +               cpu53: cpu@35 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <53>;
> > > +                       reg = <0x35>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1956,9 +1956,9 @@ cpu53_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu54: cpu@54 {
> > > +               cpu54: cpu@36 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <54>;
> > > +                       reg = <0x36>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -1992,9 +1992,9 @@ cpu54_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu55: cpu@55 {
> > > +               cpu55: cpu@37 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <55>;
> > > +                       reg = <0x37>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2028,9 +2028,9 @@ cpu55_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu56: cpu@56 {
> > > +               cpu56: cpu@38 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <56>;
> > > +                       reg = <0x38>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2064,9 +2064,9 @@ cpu56_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu57: cpu@57 {
> > > +               cpu57: cpu@39 {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <57>;
> > > +                       reg = <0x39>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2100,9 +2100,9 @@ cpu57_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu58: cpu@58 {
> > > +               cpu58: cpu@3a {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <58>;
> > > +                       reg = <0x3a>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2136,9 +2136,9 @@ cpu58_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu59: cpu@59 {
> > > +               cpu59: cpu@3b {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <59>;
> > > +                       reg = <0x3b>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2172,9 +2172,9 @@ cpu59_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu60: cpu@60 {
> > > +               cpu60: cpu@3c {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <60>;
> > > +                       reg = <0x3c>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2208,9 +2208,9 @@ cpu60_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu61: cpu@61 {
> > > +               cpu61: cpu@3d {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <61>;
> > > +                       reg = <0x3d>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2244,9 +2244,9 @@ cpu61_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu62: cpu@62 {
> > > +               cpu62: cpu@3e {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <62>;
> > > +                       reg = <0x3e>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > @@ -2280,9 +2280,9 @@ cpu62_intc: interrupt-controller {
> > >                         };
> > >                 };
> > >
> > > -               cpu63: cpu@63 {
> > > +               cpu63: cpu@3f {
> > >                         compatible = "thead,c920", "riscv";
> > > -                       reg = <63>;
> > > +                       reg = <0x3f>;
> > >                         i-cache-block-size = <64>;
> > >                         i-cache-size = <65536>;
> > >                         i-cache-sets = <512>;
> > > --
> > > 2.53.0
> > >
> >
> >
> > --
> > Best Regards
> >  Guo Ren



--
Best Regards
 Guo Ren

^ permalink raw reply

* [PATCH v5 4/4] irqchip/aspeed-intc: Remove AST2700-A0 support
From: Ryan Chen @ 2026-04-07  3:08 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Thomas Gleixner
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-riscv, Ryan Chen
In-Reply-To: <20260407-irqchip-v5-0-c0b0a300a057@aspeedtech.com>

The existing AST2700 interrupt controller driver
("aspeed,ast2700-intc-ic") was written against the A0 pre-production
design.

From A1 onwards (retained in the A2 production silicon), the interrupt
fabric was re-architected: interrupt routing is programmable and
interrupt outputs can be directed to multiple upstream controllers
(PSP GIC, Secondary Service Processor (SSP) NVIC, Tertiary Service
Processor (TSP) NVIC, and Boot MCU interrupt controller). This design
requires route resolution and a controller hierarchy model which the
A0 driver cannot represent.

Remove driver support for A0 in favour of the driver for the A2
production design.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
 drivers/irqchip/Makefile          |   1 -
 drivers/irqchip/irq-aspeed-intc.c | 139 --------------------------------------
 2 files changed, 140 deletions(-)

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index ac04a4b97797..3d02441b3ee6 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -92,7 +92,6 @@ 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_ASPEED_AST2700_INTC_TEST)	+= irq-ast2700-intc0-test.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
 obj-$(CONFIG_STM32_EXTI) 		+= irq-stm32-exti.o
 obj-$(CONFIG_QCOM_IRQ_COMBINER)		+= qcom-irq-combiner.o
diff --git a/drivers/irqchip/irq-aspeed-intc.c b/drivers/irqchip/irq-aspeed-intc.c
deleted file mode 100644
index 4fb0dd8349da..000000000000
--- a/drivers/irqchip/irq-aspeed-intc.c
+++ /dev/null
@@ -1,139 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  Aspeed Interrupt Controller.
- *
- *  Copyright (C) 2023 ASPEED Technology Inc.
- */
-
-#include <linux/bitops.h>
-#include <linux/irq.h>
-#include <linux/irqchip.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/irqdomain.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-
-#define INTC_INT_ENABLE_REG	0x00
-#define INTC_INT_STATUS_REG	0x04
-#define INTC_IRQS_PER_WORD	32
-
-struct aspeed_intc_ic {
-	void __iomem		*base;
-	raw_spinlock_t		gic_lock;
-	raw_spinlock_t		intc_lock;
-	struct irq_domain	*irq_domain;
-};
-
-static void aspeed_intc_ic_irq_handler(struct irq_desc *desc)
-{
-	struct aspeed_intc_ic *intc_ic = irq_desc_get_handler_data(desc);
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-
-	chained_irq_enter(chip, desc);
-
-	scoped_guard(raw_spinlock, &intc_ic->gic_lock) {
-		unsigned long bit, status;
-
-		status = readl(intc_ic->base + INTC_INT_STATUS_REG);
-		for_each_set_bit(bit, &status, INTC_IRQS_PER_WORD) {
-			generic_handle_domain_irq(intc_ic->irq_domain, bit);
-			writel(BIT(bit), intc_ic->base + INTC_INT_STATUS_REG);
-		}
-	}
-
-	chained_irq_exit(chip, desc);
-}
-
-static void aspeed_intc_irq_mask(struct irq_data *data)
-{
-	struct aspeed_intc_ic *intc_ic = irq_data_get_irq_chip_data(data);
-	unsigned int mask = readl(intc_ic->base + INTC_INT_ENABLE_REG) & ~BIT(data->hwirq);
-
-	guard(raw_spinlock)(&intc_ic->intc_lock);
-	writel(mask, intc_ic->base + INTC_INT_ENABLE_REG);
-}
-
-static void aspeed_intc_irq_unmask(struct irq_data *data)
-{
-	struct aspeed_intc_ic *intc_ic = irq_data_get_irq_chip_data(data);
-	unsigned int unmask = readl(intc_ic->base + INTC_INT_ENABLE_REG) | BIT(data->hwirq);
-
-	guard(raw_spinlock)(&intc_ic->intc_lock);
-	writel(unmask, intc_ic->base + INTC_INT_ENABLE_REG);
-}
-
-static struct irq_chip aspeed_intc_chip = {
-	.name			= "ASPEED INTC",
-	.irq_mask		= aspeed_intc_irq_mask,
-	.irq_unmask		= aspeed_intc_irq_unmask,
-};
-
-static int aspeed_intc_ic_map_irq_domain(struct irq_domain *domain, unsigned int irq,
-					 irq_hw_number_t hwirq)
-{
-	irq_set_chip_and_handler(irq, &aspeed_intc_chip, handle_level_irq);
-	irq_set_chip_data(irq, domain->host_data);
-
-	return 0;
-}
-
-static const struct irq_domain_ops aspeed_intc_ic_irq_domain_ops = {
-	.map = aspeed_intc_ic_map_irq_domain,
-};
-
-static int __init aspeed_intc_ic_of_init(struct device_node *node,
-					 struct device_node *parent)
-{
-	struct aspeed_intc_ic *intc_ic;
-	int irq, i, ret = 0;
-
-	intc_ic = kzalloc_obj(*intc_ic);
-	if (!intc_ic)
-		return -ENOMEM;
-
-	intc_ic->base = of_iomap(node, 0);
-	if (!intc_ic->base) {
-		pr_err("Failed to iomap intc_ic base\n");
-		ret = -ENOMEM;
-		goto err_free_ic;
-	}
-	writel(0xffffffff, intc_ic->base + INTC_INT_STATUS_REG);
-	writel(0x0, intc_ic->base + INTC_INT_ENABLE_REG);
-
-	intc_ic->irq_domain = irq_domain_create_linear(of_fwnode_handle(node), INTC_IRQS_PER_WORD,
-						    &aspeed_intc_ic_irq_domain_ops, intc_ic);
-	if (!intc_ic->irq_domain) {
-		ret = -ENOMEM;
-		goto err_iounmap;
-	}
-
-	raw_spin_lock_init(&intc_ic->gic_lock);
-	raw_spin_lock_init(&intc_ic->intc_lock);
-
-	/* Check all the irq numbers valid. If not, unmaps all the base and frees the data. */
-	for (i = 0; i < of_irq_count(node); i++) {
-		irq = irq_of_parse_and_map(node, i);
-		if (!irq) {
-			pr_err("Failed to get irq number\n");
-			ret = -EINVAL;
-			goto err_iounmap;
-		}
-	}
-
-	for (i = 0; i < of_irq_count(node); i++) {
-		irq = irq_of_parse_and_map(node, i);
-		irq_set_chained_handler_and_data(irq, aspeed_intc_ic_irq_handler, intc_ic);
-	}
-
-	return 0;
-
-err_iounmap:
-	iounmap(intc_ic->base);
-err_free_ic:
-	kfree(intc_ic);
-	return ret;
-}
-
-IRQCHIP_DECLARE(ast2700_intc_ic, "aspeed,ast2700-intc-ic", aspeed_intc_ic_of_init);

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 3/4] irqchip/ast2700-intc: Add KUnit tests for route resolution
From: Ryan Chen @ 2026-04-07  3:08 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Thomas Gleixner
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-riscv, Ryan Chen
In-Reply-To: <20260407-irqchip-v5-0-c0b0a300a057@aspeedtech.com>

Add a KUnit suite for aspeed_intc0_resolve_route().

Cover invalid arguments, invalid domain/range data, connected and
disconnected mappings, and malformed upstream range cases.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>

---
Changes in v5:
- modify enable CONFIG_PROVE_LOCKING irq lock inversion dependency
  detected.
Changes in v4:
- fix warning: the frame size of 1296 bytes is larger than 1280 bytes.
Changes in v2:
- add line break before include "irq-ast2700.h"
- remove pointless newline.
- rename arm_gicv3_fwnode_read_string_array to
  gicv3_fwnode_read_string_array
- add .kunitconfig file
---
 drivers/irqchip/.kunitconfig             |   5 +
 drivers/irqchip/Kconfig                  |  11 +
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-ast2700-intc0-test.c | 473 +++++++++++++++++++++++++++++++
 drivers/irqchip/irq-ast2700-intc0.c      |   3 +-
 5 files changed, 492 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/.kunitconfig b/drivers/irqchip/.kunitconfig
new file mode 100644
index 000000000000..00a12703f635
--- /dev/null
+++ b/drivers/irqchip/.kunitconfig
@@ -0,0 +1,5 @@
+CONFIG_KUNIT=y
+CONFIG_OF=y
+CONFIG_COMPILE_TEST=y
+CONFIG_ASPEED_AST2700_INTC=y
+CONFIG_ASPEED_AST2700_INTC_TEST=y
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 0156fee89b2c..143af3f30a4b 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -122,6 +122,17 @@ config ASPEED_AST2700_INTC
 
 	  If unsure, say N.
 
+config ASPEED_AST2700_INTC_TEST
+	bool "Tests for the ASPEED AST2700 Interrupt Controller"
+	depends on ASPEED_AST2700_INTC && KUNIT=y
+	default KUNIT_ALL_TESTS
+	help
+	  Enable KUnit tests for AST2700 INTC route resolution.
+	  The tests exercise error handling and route selection paths.
+	  This option is intended for test builds.
+
+	  If unsure, say N.
+
 config ATMEL_AIC_IRQ
 	bool
 	select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 62790663f982..ac04a4b97797 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -90,6 +90,7 @@ 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_ASPEED_AST2700_INTC_TEST)	+= irq-ast2700-intc0-test.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..d49784509ac7
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700-intc0-test.c
@@ -0,0 +1,473 @@
+// 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 u32 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, -ENOENT);
+
+	rc = aspeed_intc0_resolve_route(&c0domain, ARRAY_SIZE(c1outs), c1outs,
+					0, c1ranges, &resolved);
+	KUNIT_EXPECT_EQ(test, rc, -ENOENT);
+}
+
+static int gicv3_fwnode_read_string_array(const struct fwnode_handle *fwnode,
+					  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 = 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 u32 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";
+	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 u32 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 u32 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 u32 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 u32 c1outs[] = { 1 };
+	struct aspeed_intc_interrupt_range resolved;
+	static 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 u32 c1outs[] = { 0 };
+	struct aspeed_intc_interrupt_range resolved;
+	static 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 u32 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 u32 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
index 65e17b2dc6fa..14b8b88f1179 100644
--- a/drivers/irqchip/irq-ast2700-intc0.c
+++ b/drivers/irqchip/irq-ast2700-intc0.c
@@ -311,7 +311,8 @@ int aspeed_intc0_resolve_route(const struct irq_domain *c0domain, size_t nc1outs
 	if (nc1outs == 0 || nc1ranges == 0)
 		return -ENOENT;
 
-	if (!fwnode_device_is_compatible(c0domain->fwnode, "aspeed,ast2700-intc0"))
+	if (!IS_ENABLED(CONFIG_ASPEED_AST2700_INTC_TEST) &&
+	    !fwnode_device_is_compatible(c0domain->fwnode, "aspeed,ast2700-intc0"))
 		return -ENODEV;
 
 	intc0 = c0domain->host_data;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 2/4] irqchip/ast2700-intc: Add AST2700-A2 support
From: Ryan Chen @ 2026-04-07  3:08 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Thomas Gleixner
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-riscv, Ryan Chen
In-Reply-To: <20260407-irqchip-v5-0-c0b0a300a057@aspeedtech.com>

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>
---
Changes in v5:
- reduce unnecessary line breaks.
- fix enable CONFIG_PROVE_LOCKING irq lock inversion dependency
  detected.

Changes in v2:
- remove typedef u32 aspeed_intc_output_t
- modify #include <asm-generic/errno.h> to <linux/err.h>
- add newline after include "irq-ast2700.h"
- make defines tabular
- Struct declarations should align the struct member names in a table
- modify raw_spinlock_irqsave() to raw_spin_lock()
- use u32 ier replace mask/unmask
- remove pointless line break
- refine aspeed_intc0_routes, aspeed_intc1_routes array
- remove range_contains_element(), use in_range32()
- remove dev_dbg()
- remove EXPORT_SYMBOL_GPL(aspeed_intc0_resolve_route);
- make irq_set_chip_and_handler() with one line
- replace magic constants to macro define
- move struct aspeed_intc0 to irq-ast2700.h
- add mcro define for upstream param
---
 drivers/irqchip/Kconfig             |  12 +
 drivers/irqchip/Makefile            |   1 +
 drivers/irqchip/irq-ast2700-intc0.c | 581 ++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-ast2700-intc1.c | 280 +++++++++++++++++
 drivers/irqchip/irq-ast2700.c       | 107 +++++++
 drivers/irqchip/irq-ast2700.h       |  48 +++
 6 files changed, 1029 insertions(+)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f07b00d7fef9..0156fee89b2c 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -110,6 +110,18 @@ 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
+	help
+	  Enable support for the ASPEED AST2700 interrupt controller.
+	  This driver handles interrupt, routing and merged interrupt
+	  sources to upstream parent interrupt controllers.
+
+	  If unsure, say N.
+
 config ATMEL_AIC_IRQ
 	bool
 	select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 26aa3b6ec99f..62790663f982 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -89,6 +89,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.c b/drivers/irqchip/irq-ast2700-intc0.c
new file mode 100644
index 000000000000..65e17b2dc6fa
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700-intc0.c
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Aspeed AST2700 Interrupt Controller.
+ *
+ *  Copyright (C) 2026 ASPEED Technology Inc.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/err.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/overflow.h>
+#include <linux/property.h>
+#include <linux/spinlock.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 INTC0_IN_NUM		480
+#define INTC0_ROUTE_NUM		5
+#define INTC0_INTM_NUM		50
+#define INTC0_ROUTE_BITS	3
+
+#define GIC_P2P_SPI_END		128
+#define INTC0_SWINT_OUT_BASE	144
+
+#define INTC0_SWINT_IER		0x10
+#define INTC0_SWINT_ISR		0x14
+#define INTC0_INTBANKX_IER	0x1000
+#define INTC0_INTBANK_SIZE	0x100
+#define INTC0_INTBANK_GROUPS	11
+#define INTC0_INTBANKS_PER_GRP	3
+#define INTC0_INTMX_IER		0x1b00
+#define INTC0_INTMX_ISR		0x1b04
+#define INTC0_INTMX_BANK_SIZE	0x10
+#define INTC0_INTM_BANK_NUM	3
+#define INTC0_IRQS_PER_BANK	32
+#define INTM_IRQS_PER_BANK	10
+#define INTC0_SEL_BASE			0x200
+#define INTC0_SEL_BANK_SIZE		0x4
+#define INTC0_SEL_ROUTE_SIZE	0x100
+
+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;
+	u32 ier;
+
+	guard(raw_spinlock)(&intc0->intc_lock);
+	ier = readl(intc0->base + INTC0_SWINT_IER) & ~BIT(bit);
+	writel(ier, 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;
+	u32 ier;
+
+	guard(raw_spinlock)(&intc0->intc_lock);
+	ier = readl(intc0->base + INTC0_SWINT_IER) | BIT(bit);
+	writel(ier, 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;
+	u32 ier;
+
+	guard(raw_spinlock)(&intc0->intc_lock);
+	ier = readl(intc0->base + INTC0_INTMX_IER + bank * INTC0_INTMX_BANK_SIZE) & ~BIT(bit);
+	writel(ier, intc0->base + INTC0_INTMX_IER + bank * INTC0_INTMX_BANK_SIZE);
+	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;
+	u32 ier;
+
+	guard(raw_spinlock)(&intc0->intc_lock);
+	ier = readl(intc0->base + INTC0_INTMX_IER + bank * INTC0_INTMX_BANK_SIZE) | BIT(bit);
+	writel(ier, intc0->base + INTC0_INTMX_IER + bank * INTC0_INTMX_BANK_SIZE);
+	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 * INTC0_INTMX_BANK_SIZE);
+	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,
+};
+
+static const u32 aspeed_intc0_routes[INTC0_IN_NUM / INTC0_IRQS_PER_BANK][INTC0_ROUTE_NUM] = {
+	{ 0, 256, 426, AST2700_INTC_INVALID_ROUTE, AST2700_INTC_INVALID_ROUTE },
+	{ 32, 288, 458, AST2700_INTC_INVALID_ROUTE, AST2700_INTC_INVALID_ROUTE },
+	{ 64, 320, 490, AST2700_INTC_INVALID_ROUTE, AST2700_INTC_INVALID_ROUTE },
+	{ 96, 352, 522, AST2700_INTC_INVALID_ROUTE, AST2700_INTC_INVALID_ROUTE },
+	{ 128, 384, 554, 160, 176 },
+	{ 129, 385, 555, 161, 177 },
+	{ 130, 386, 556, 162, 178 },
+	{ 131, 387, 557, 163, 179 },
+	{ 132, 388, 558, 164, 180 },
+	{ 133, 544, 714, 165, 181 },
+	{ 134, 545, 715, 166, 182 },
+	{ 135, 546, 706, 167, 183 },
+	{ 136, 547, 707, 168, 184 },
+	{ 137, 548, 708, 169, 185 },
+	{ 138, 549, 709, 170, 186 },
+};
+
+static const u32 aspeed_intc0_intm_routes[INTC0_INTM_NUM / INTM_IRQS_PER_BANK] = {
+	192, 416, 586, 208, 224
+};
+
+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, base;
+
+	if (!in_range32(outpin, range->start, range->count))
+		return -ENOENT;
+
+	if (range->upstream.param_count == 0)
+		return -EINVAL;
+
+	base = range->upstream.param[ASPEED_INTC_RANGES_BASE];
+	offset = outpin - range->start;
+	if (check_add_overflow(base, offset, input)) {
+		dev_warn(intc0->dev, "%s: Arithmetic overflow for input derivation: %u + %u\n",
+			 __func__, base, offset);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int 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];
+
+		if (!in_range32(output, range.start, range.count))
+			continue;
+
+		if (range.upstream.fwnode != parent)
+			continue;
+
+		if (resolved) {
+			resolved->start = output;
+			resolved->count = 1;
+			resolved->upstream = range.upstream;
+			resolved->upstream.param[ASPEED_INTC_RANGES_COUNT] +=
+				output - range.start;
+		}
+
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+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)
+{
+	int rc = -ENOENT;
+	u32 c0o;
+
+	if (input < INT_NUM) {
+		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 / INTC0_IRQS_PER_BANK][i];
+			if (c0o == AST2700_INTC_INVALID_ROUTE)
+				continue;
+
+			if (input < GIC_P2P_SPI_END)
+				c0o += input % INTC0_IRQS_PER_BANK;
+
+			rc = resolve_parent_range_for_output(intc0, parent, c0o, resolved);
+			if (!rc)
+				return (int)i;
+		}
+	} else if (input < (INT_NUM + INTM_NUM)) {
+		c0o = aspeed_intc0_intm_routes[(input - INT_NUM) / INTM_IRQS_PER_BANK];
+		c0o += ((input - INT_NUM) % INTM_IRQS_PER_BANK);
+		return resolve_parent_range_for_output(intc0, parent, c0o, resolved);
+	} else if (input < (INT_NUM + INTM_NUM + SWINT_NUM)) {
+		c0o = input - SWINT_BASE + INTC0_SWINT_OUT_BASE;
+		return resolve_parent_range_for_output(intc0, parent, c0o, resolved);
+	} else {
+		return -ENOENT;
+	}
+
+	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 u32 *c1outs, size_t nc1ranges,
+			       const struct aspeed_intc_interrupt_range *c1ranges,
+			       struct aspeed_intc_interrupt_range *resolved)
+{
+	struct fwnode_handle *parent_fwnode;
+	struct aspeed_intc0 *intc0;
+	int ret;
+
+	if (!c0domain || !resolved)
+		return -EINVAL;
+
+	if (nc1outs > INT_MAX)
+		return -EINVAL;
+
+	if (nc1outs == 0 || nc1ranges == 0)
+		return -ENOENT;
+
+	if (!fwnode_device_is_compatible(c0domain->fwnode, "aspeed,ast2700-intc0"))
+		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++) {
+		u32 c1o = c1outs[i];
+
+		if (c1o == AST2700_INTC_INVALID_ROUTE)
+			continue;
+
+		for (size_t j = 0; j < nc1ranges; j++) {
+			struct aspeed_intc_interrupt_range c1r = c1ranges[j];
+			u32 input;
+
+			/*
+			 * 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 == c1r.domain ||
+			      IS_ENABLED(CONFIG_ASPEED_AST2700_INTC_TEST)))
+				continue;
+
+			ret = resolve_input_from_child_ranges(intc0, &c1r, c1o, &input);
+			if (ret)
+				continue;
+
+			/*
+			 * INTC1 should never request routes for peripheral interrupt sources
+			 * directly attached to INTC0.
+			 */
+			if (input < GIC_P2P_SPI_END)
+				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[ASPEED_INTC_RANGES_BASE] = input;
+			/* Cast protected by prior test against nc1outs */
+			return (int)i;
+		}
+	}
+
+	return -ENOENT;
+}
+
+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);
+	unsigned long hwirq = data->hwirq;
+	int route, bank, bit;
+	u32 mask;
+
+	if (hwirq >= INT0_NUM)
+		return -EINVAL;
+
+	if (in_range32(hwirq, INTM_BASE, INTM_NUM + SWINT_NUM))
+		return 0;
+
+	bank = hwirq / INTC0_IRQS_PER_BANK;
+	bit = hwirq % INTC0_IRQS_PER_BANK;
+	mask = BIT(bit);
+
+	route = resolve_parent_route_for_input(intc0, intc0->local->parent->fwnode,
+					       hwirq, NULL);
+	if (route < 0)
+		return route;
+
+	guard(raw_spinlock)(&intc0->intc_lock);
+	for (int i = 0; i < INTC0_ROUTE_BITS; i++) {
+		void __iomem *sel = intc0->base + INTC0_SEL_BASE +
+				    (bank * INTC0_SEL_BANK_SIZE) +
+				    (INTC0_SEL_ROUTE_SIZE * i);
+		u32 reg = readl(sel);
+
+		if (route & BIT(i))
+			reg |= mask;
+		else
+			reg &= ~mask;
+
+		writel(reg, sel);
+		if (readl(sel) != reg)
+			return -EACCES;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops aspeed_intc0_irq_domain_ops = {
+	.translate	= aspeed_intc0_irq_domain_translate,
+	.activate	= aspeed_intc0_irq_domain_activate,
+	.alloc		= aspeed_intc0_irq_domain_alloc,
+	.free		= irq_domain_free_irqs_common,
+	.map		= aspeed_intc0_irq_domain_map,
+};
+
+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)
+{
+	for (int i = 0; i < INTC0_INTBANK_GROUPS; i++) {
+		for (int j = 0; j < INTC0_INTBANKS_PER_GRP; j++) {
+			u32 base = INTC0_INTBANKX_IER +
+				   (INTC0_INTBANK_SIZE * i) +
+				   (INTC0_INTMX_BANK_SIZE * j);
+
+			writel(0, intc0->base + base);
+		}
+	}
+}
+
+static void aspeed_intc0_disable_intm(struct aspeed_intc0 *intc0)
+{
+	for (int i = 0; i < INTC0_INTM_BANK_NUM; i++)
+		writel(0, intc0->base + INTC0_INTMX_IER + (INTC0_INTMX_BANK_SIZE * i));
+}
+
+static int aspeed_intc0_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_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", aspeed_intc0_probe)
+IRQCHIP_PLATFORM_DRIVER_END(ast2700_intc0)
diff --git a/drivers/irqchip/irq-ast2700-intc1.c b/drivers/irqchip/irq-ast2700-intc1.c
new file mode 100644
index 000000000000..59e8f0d5ddcd
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700-intc1.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Aspeed AST2700 Interrupt Controller.
+ *
+ *  Copyright (C) 2026 ASPEED Technology Inc.
+ */
+
+#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_BANK_SIZE		0x10
+#define INTC1_SEL_BASE			0x80
+#define INTC1_SEL_BANK_SIZE		0x4
+#define INTC1_SEL_ROUTE_SIZE	0x20
+#define INTC1_IRQS_PER_BANK		32
+#define INTC1_BANK_NUM			6
+#define INTC1_ROUTE_NUM			7
+#define INTC1_IN_NUM			192
+#define INTC1_BOOTMCU_ROUTE		6
+#define INTC1_ROUTE_SELECTOR_BITS	3
+#define INTC1_ROUTE_IRQS_PER_GROUP	32
+#define INTC1_ROUTE_SHIFT		5
+
+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(0, intc1->base + INTC1_IER + (INTC1_BANK_SIZE * i));
+}
+
+static void aspeed_intc1_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 + (INTC1_BANK_SIZE * 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 + (INTC1_BANK_SIZE * 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;
+	u32 ier;
+
+	guard(raw_spinlock)(&intc1->intc_lock);
+	ier = readl(intc1->base + INTC1_IER + (INTC1_BANK_SIZE * bank)) & ~BIT(bit);
+	writel(ier, intc1->base + INTC1_IER + (INTC1_BANK_SIZE * 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;
+	u32 ier;
+
+	guard(raw_spinlock)(&intc1->intc_lock);
+	ier = readl(intc1->base + INTC1_IER + (INTC1_BANK_SIZE * bank)) | BIT(bit);
+	writel(ier, intc1->base + INTC1_IER + (INTC1_BANK_SIZE * 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_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;
+}
+
+/*
+ * 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 u32
+aspeed_intc1_routes[INTC1_IN_NUM / INTC1_ROUTE_IRQS_PER_GROUP][INTC1_ROUTE_NUM] = {
+	{ 0, AST2700_INTC_INVALID_ROUTE, 10, 20, 30, 40, 50 },
+	{ 1, AST2700_INTC_INVALID_ROUTE, 11, 21, 31, 41, 50 },
+	{ 2, AST2700_INTC_INVALID_ROUTE, 12, 22, 32, 42, 50 },
+	{ 3, AST2700_INTC_INVALID_ROUTE, 13, 23, 33, 43, 50 },
+	{ 4, AST2700_INTC_INVALID_ROUTE, 14, 24, 34, 44, 50 },
+	{ 5, AST2700_INTC_INVALID_ROUTE, 15, 25, 35, 45, 50 },
+};
+
+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);
+	struct aspeed_intc_interrupt_range resolved;
+	int rc, bank, bit;
+	u32 mask;
+
+	if (WARN_ON_ONCE((data->hwirq >> INTC1_ROUTE_SHIFT) >= ARRAY_SIZE(aspeed_intc1_routes)))
+		return -EINVAL;
+
+	/*
+	 * 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 >> INTC1_ROUTE_SHIFT],
+					intc1->ranges.nranges,
+					intc1->ranges.ranges, &resolved);
+	if (rc < 0) {
+		if (!fwnode_device_is_compatible(intc1->upstream->fwnode, "riscv,aplic")) {
+			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;
+	}
+
+	bank = data->hwirq / INTC1_IRQS_PER_BANK;
+	bit = data->hwirq % INTC1_IRQS_PER_BANK;
+	mask = BIT(bit);
+
+	guard(raw_spinlock)(&intc1->intc_lock);
+	for (int i = 0; i < INTC1_ROUTE_SELECTOR_BITS; i++) {
+		void __iomem *sel = intc1->base + INTC1_SEL_BASE +
+				    (bank * INTC1_SEL_BANK_SIZE) +
+				    (INTC1_SEL_ROUTE_SIZE * i);
+		u32 reg = readl(sel);
+
+		if (rc & BIT(i))
+			reg |= mask;
+		else
+			reg &= ~mask;
+
+		writel(reg, sel);
+		if (readl(sel) != reg)
+			return -EACCES;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops aspeed_intc1_irq_domain_ops = {
+	.map		= aspeed_intc1_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)
+{
+	for (unsigned int i = 0; i < intc1->ranges.nranges; i++) {
+		struct aspeed_intc_interrupt_range *r =
+			&intc1->ranges.ranges[i];
+
+		if (intc1->upstream != r->domain)
+			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[ASPEED_INTC_RANGES_BASE] + k;
+
+			irq = irq_create_of_mapping(&parent_irq);
+			if (!irq)
+				continue;
+
+			irq_set_chained_handler_and_data(irq,
+							 aspeed_intc1_irq_handler, intc1);
+		}
+	}
+}
+
+static int aspeed_intc1_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"))
+		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_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", aspeed_intc1_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..1e4c4a624dbf
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Aspeed AST2700 Interrupt Controller.
+ *
+ *  Copyright (C) 2026 ASPEED Technology Inc.
+ */
+#include "irq-ast2700.h"
+
+#define ASPEED_INTC_RANGE_FIXED_CELLS	3U
+#define ASPEED_INTC_RANGE_OFF_START	0U
+#define ASPEED_INTC_RANGE_OFF_COUNT	1U
+#define ASPEED_INTC_RANGE_OFF_PHANDLE	2U
+
+/**
+ * aspeed_intc_populate_ranges
+ * @dev: Device owning the interrupt controller node.
+ * @ranges: Destination for parsed range descriptors.
+ *
+ * Return: 0 on success, negative errno on error.
+ */
+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 / (ASPEED_INTC_RANGE_FIXED_CELLS * sizeof(__be32)),
+					    sizeof(*ranges->ranges),
+					    GFP_KERNEL);
+	if (!ranges->ranges)
+		return -ENOMEM;
+
+	pve = pvs + (len / sizeof(__be32));
+	for (unsigned int i = 0; pve - pvs >= ASPEED_INTC_RANGE_FIXED_CELLS; i++) {
+		struct aspeed_intc_interrupt_range *r;
+		struct device_node *target;
+		u32 target_cells;
+
+		target = of_find_node_by_phandle(be32_to_cpu(pvs[ASPEED_INTC_RANGE_OFF_PHANDLE]));
+		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 < ASPEED_INTC_RANGE_FIXED_CELLS + target_cells) {
+			of_node_put(target);
+			return -EINVAL;
+		}
+
+		r = &ranges->ranges[i];
+		r->start = be32_to_cpu(pvs[ASPEED_INTC_RANGE_OFF_START]);
+		r->count = be32_to_cpu(pvs[ASPEED_INTC_RANGE_OFF_COUNT]);
+
+		{
+			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[ASPEED_INTC_RANGE_FIXED_CELLS + j]);
+
+			of_phandle_args_to_fwspec(target, args.args,
+						  args.args_count,
+						  &r->upstream);
+		}
+
+		of_node_put(target);
+		r->domain = irq_find_matching_fwspec(&r->upstream, DOMAIN_BUS_ANY);
+		pvs += ASPEED_INTC_RANGE_FIXED_CELLS + 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..318296638445
--- /dev/null
+++ b/drivers/irqchip/irq-ast2700.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *  Aspeed AST2700 Interrupt Controller.
+ *
+ *  Copyright (C) 2026 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)
+#define ASPEED_INTC_RANGES_BASE		0U
+#define ASPEED_INTC_RANGES_COUNT	1U
+
+struct aspeed_intc_interrupt_range {
+	u32               start;
+	u32               count;
+	struct irq_fwspec upstream;
+	struct irq_domain *domain;
+};
+
+struct aspeed_intc_interrupt_ranges {
+	struct aspeed_intc_interrupt_range *ranges;
+	unsigned int                       nranges;
+};
+
+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;
+};
+
+int aspeed_intc_populate_ranges(struct device *dev,
+				struct aspeed_intc_interrupt_ranges *ranges);
+
+int aspeed_intc0_resolve_route(const struct irq_domain *c0domain,
+			       size_t nc1outs,
+			       const u32 *c1outs,
+			       size_t nc1ranges,
+			       const struct aspeed_intc_interrupt_range *c1ranges,
+			       struct aspeed_intc_interrupt_range *resolved);
+
+#endif

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 1/4] dt-bindings: interrupt-controller: Describe AST2700-A2 hardware instead of A0
From: Ryan Chen @ 2026-04-07  3:08 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Thomas Gleixner
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-riscv, Ryan Chen
In-Reply-To: <20260407-irqchip-v5-0-c0b0a300a057@aspeedtech.com>

Introduce a new binding describing the AST2700 interrupt controller
architecture implemented in the A2 production silicon.

The AST2700 SoC has undergone multiple silicon revisions (A0, A1, A2)
prior to mass production. The interrupt architecture was substantially
reworked after the A0 revision for A1, and the A1 design is retained
unchanged in the A2 production silicon.

The existing AST2700 interrupt controller binding
("aspeed,ast2700-intc-ic")was written against the pre-production A0
design. That binding does not accurately describe the interrupt
hierarchy and routing model present in A1/A2, where interrupts can be
routed to multiple processor-local interrupt controllers (Primary
Service Processor (PSP) GIC, Secondary Service Processor (SSP)/Tertiary
Service Processor (TSP) NVICs, and BootMCU APLIC) depending on the
execution context.

Remove the binding for the pre-production A0 design in favour of the
binding for the A2 production design. There is no significant user
impact from the removal as there are no existing devicetrees in any
of Linux, u-boot or Zephyr that make use of the A0 binding.

Hardware connectivity between interrupt controllers is expressed using
the aspeed,interrupt-ranges property.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>

---
Changes in v3:
- squash patch 5/5.
- modify wrap lines at 80 char.
- modify maintainers name and email.
- modify typo Sevice-> Service
Changes in v2:
- Describe AST2700 A0/A1/A2 design evolution.
- Drop the redundant '-ic' suffix from compatible strings.
- Expand commit message to match the series cover letter context.
- fix ascii diagram
- remove intc0 label
- remove spaces before >
- drop intc1 example
---
 .../interrupt-controller/aspeed,ast2700-intc.yaml  |  90 ----------
 .../aspeed,ast2700-interrupt.yaml                  | 188 +++++++++++++++++++++
 2 files changed, 188 insertions(+), 90 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
deleted file mode 100644
index 258d21fe6e35..000000000000
--- a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-intc.yaml
+++ /dev/null
@@ -1,90 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-intc.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Aspeed AST2700 Interrupt Controller
-
-description:
-  This interrupt controller hardware is second level interrupt controller that
-  is hooked to a parent interrupt controller. It's useful to combine multiple
-  interrupt sources into 1 interrupt to parent interrupt controller.
-
-maintainers:
-  - Kevin Chen <kevin_chen@aspeedtech.com>
-
-properties:
-  compatible:
-    enum:
-      - aspeed,ast2700-intc-ic
-
-  reg:
-    maxItems: 1
-
-  interrupt-controller: true
-
-  '#interrupt-cells':
-    const: 1
-    description:
-      The first cell is the IRQ number, the second cell is the trigger
-      type as defined in interrupt.txt in this directory.
-
-  interrupts:
-    minItems: 1
-    maxItems: 10
-    description: |
-      Depend to which INTC0 or INTC1 used.
-      INTC0 and INTC1 are two kinds of interrupt controller with enable and raw
-      status registers for use.
-      INTC0 is used to assert GIC if interrupt in INTC1 asserted.
-      INTC1 is used to assert INTC0 if interrupt of modules asserted.
-      +-----+   +-------+     +---------+---module0
-      | GIC |---| INTC0 |--+--| INTC1_0 |---module2
-      |     |   |       |  |  |         |---...
-      +-----+   +-------+  |  +---------+---module31
-                           |
-                           |   +---------+---module0
-                           +---| INTC1_1 |---module2
-                           |   |         |---...
-                           |   +---------+---module31
-                          ...
-                           |   +---------+---module0
-                           +---| INTC1_5 |---module2
-                               |         |---...
-                               +---------+---module31
-
-required:
-  - compatible
-  - reg
-  - interrupt-controller
-  - '#interrupt-cells'
-  - interrupts
-
-additionalProperties: false
-
-examples:
-  - |
-    #include <dt-bindings/interrupt-controller/arm-gic.h>
-
-    bus {
-        #address-cells = <2>;
-        #size-cells = <2>;
-
-        interrupt-controller@12101b00 {
-            compatible = "aspeed,ast2700-intc-ic";
-            reg = <0 0x12101b00 0 0x10>;
-            #interrupt-cells = <1>;
-            interrupt-controller;
-            interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
-                         <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
-        };
-    };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-interrupt.yaml b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-interrupt.yaml
new file mode 100644
index 000000000000..a62f0fd2435b
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700-interrupt.yaml
@@ -0,0 +1,188 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2700-interrupt.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2700 Interrupt Controllers (INTC0/INTC1)
+
+description: |
+  The ASPEED AST2700 SoC integrates two interrupt controller designs:
+
+    - INTC0: Primary controller that routes interrupt sources to upstream,
+      processor-specific interrupt controllers
+
+    - INTC1: Secondary controller whose interrupt outputs feed into INTC0
+
+  The SoC contains four processors to which interrupts can be routed:
+
+    - PSP: Primary Service Processor (Cortex-A35)
+    - SSP: Secondary Service Processor (Cortex-M4)
+    - TSP: Tertiary Service Processor (Cortex-M4)
+    - BMCU: Boot MCU (a RISC-V microcontroller)
+
+  The following diagram illustrates the overall architecture of the
+  ASPEED AST2700 interrupt controllers:
+
+                  +-----------+                +-----------+
+                  |   INTC0   |                | INTC1(0)  |
+                  +-----------+                +-----------+
+                  |   Router  | +-----------+  |   Router  |
+                  | out   int | +Peripheral +  | out   int |
+  +-----------+   |  0     0  <-+Controllers+  | INTM      | +-----------+
+  |PSP GIC  <-|---+  .     .  | +-----------+  |  .     .  <-+Peripheral +
+  +-----------+   |  .     .  |                |  .     .  | +Controllers+
+  +-----------+   |  .     .  |                |  .     .  | +-----------+
+  |SSP NVIC <-|---+  .     .  <----------------+  .     .  |
+  +-----------+   |  .     .  |                |  .     .  |
+  +-----------+   |  .     .  <--------        |  .     .  |
+  |TSP NVIC <-|---+  .     .  |       |    ----+  .     .  |
+  +-----------+   |  .     .  |       |    |   |  O     P  |
+                  |  .     .  |       |    |   +-----------+
+                  |  .     .  <----   |    --------------------
+                  |  .     .  |   |   |        +-----------+  |
+                  |  M     N  |   |   ---------+  INTC1(1) |  |
+                  +-----------+   |            +-----------+  |
+                                  |                  .        |
+                                  |            +-----------+  |
+                                  -------------+  INTC1(N) |  |
+                                               +-----------+  |
+  +--------------+                                            |
+  + BMCU APLIC <-+---------------------------------------------
+  +--------------+
+
+  INTC0 supports:
+    - 128 local peripheral interrupt inputs
+    - Fan-in from up to three INTC1 instances via banked interrupt lines (INTM)
+    - Local peripheral interrupt outputs
+    - Merged interrupt outputs
+    - Software interrupt outputs (SWINT)
+    - Configurable interrupt routes targeting the PSP, SSP, and TSP
+
+  INTC1 supports:
+    - 192 local peripheral interrupt inputs
+    - Banked interrupt outputs (INTM, 5 x 6 banks x 32 interrupts per bank)
+    - Configurable interrupt routes targeting the PSP, SSP, TSP, and BMCU
+
+  One INTC1 instance is always present, on the SoC's IO die. A further two
+  instances may be attached to the SoC's one INTC0 instance via LTPI (LVDS
+  Tunneling Protocol & Interface).
+
+  Interrupt numbering model
+  -------------------------
+  The binding uses a controller-local numbering model. Peripheral device
+  nodes use the INTCx local interrupt number (hwirq) in their 'interrupts' or
+  'interrupts-extended' properties.
+
+  For AST2700, INTC0 exposes the following (inclusive) input ranges:
+
+    - 000..479: Independent interrupts
+    - 480..489: INTM0-INTM9
+    - 490..499: INTM10-INTM19
+    - 500..509: INTM20-INTM29
+    - 510..519: INTM30-INTM39
+    - 520..529: INTM40-INTM49
+
+  INTC0's (inclusive) output ranges are as follows:
+
+    - 000..127: 1:1 local peripheral interrupt output to PSP
+    - 144..151: Software interrupts from the SSP output to PSP
+    - 152..159: Software interrupts from the TSP output to PSP
+    - 192..201: INTM0-INTM9 banked outputs to PSP
+    - 208..217: INTM30-INTM39 banked outputs to PSP
+    - 224..233: INTM40-INTM49 banked outputs to PSP
+    - 256..383: 1:1 local peripheral interrupt output to SSP
+    - 384..393: INTM10-INTM19 banked outputs to SSP
+    - 400..407: Software interrupts from the PSP output to SSP
+    - 408..415: Software interrupts from the TSP output to SSP
+    - 426..553: 1:1 local peripheral interrupt output to TSP
+    - 554..563: INTM20-INTM29 banked outputs to TSP
+    - 570..577: Software interrupts from the PSP output to TSP
+    - 578..585: Software interrupts from the SSP output to TSP
+
+  Inputs and outputs for INTC1 instances are context-dependent. However, for the
+  first instance of INTC1, the (inclusive) output ranges are:
+
+    - 00..05: INTM0-INTM5
+    - 10..15: INTM10-INTM15
+    - 20..25: INTM20-INTM25
+    - 30..35: INTM30-INTM35
+    - 40..45: INTM40-INTM45
+    - 50..50: BootMCU
+
+maintainers:
+  - Ryan Chen <ryan_chen@aspeedtech.com>
+  - Andrew Jeffery <andrew@codeconstruct.com.au>
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2700-intc0
+      - aspeed,ast2700-intc1
+
+  reg:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 1
+    description: Single cell encoding the INTC local interrupt number (hwirq).
+
+  aspeed,interrupt-ranges:
+    description: |
+      Describes how ranges of controller output pins are routed to a parent
+      interrupt controller.
+
+      Each range entry is encoded as:
+
+        <out count phandle parent-specifier...>
+
+      where:
+        - out:     First controller interrupt output index in the range.
+        - count:   Number of consecutive controller interrupt outputs and parent
+                   interrupt inputs in this range.
+        - phandle: Phandle to the parent interrupt controller node.
+        - parent-specifier: Interrupt specifier, as defined by the parent
+                            interrupt controller binding.
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 3
+    items:
+      description: Range descriptors with a parent interrupt specifier.
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - '#interrupt-cells'
+  - aspeed,interrupt-ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    interrupt-controller@12100000 {
+        compatible = "aspeed,ast2700-intc0";
+        reg = <0x12100000 0x3b00>;
+        interrupt-parent = <&gic>;
+        interrupt-controller;
+        #interrupt-cells = <1>;
+
+        aspeed,interrupt-ranges =
+          <0 128 &gic GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+          <144 8 &gic GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+          <152 8 &gic GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+          <192 10 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+          <208 10 &gic GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+          <224 10 &gic GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>,
+          <256 128 &ssp_nvic 0 0>,
+          <384 10 &ssp_nvic 160 0>,
+          <400 8 &ssp_nvic 144 0>,
+          <408 8 &ssp_nvic 152 0>,
+          <426 128 &tsp_nvic 0 0>,
+          <554 10 &tsp_nvic 160 0>,
+          <570 8 &tsp_nvic 144 0>,
+          <578 8 &tsp_nvic 152 0>;
+    };

-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 0/4] AST2700-A2 interrupt controller hierarchy and route support
From: Ryan Chen @ 2026-04-07  3:08 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Ghiti, Thomas Gleixner, Thomas Gleixner
  Cc: linux-kernel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-riscv, Ryan Chen

The AST2700 SoC has undergone multiple silicon revisions (A0, A1, A2)
prior to mass production.

A0 laid the ground-work with a split controller design (INTC0 and
INTC1) used for early development and bring-up. The interrupt
architecture was substantially reworked in the A1 to introduce an
explicit routing model and clearer hierarchy, though the split
controllers remained. The A1 interrupt architecture is unchanged in A2.

A2 is the production design. A0 and A1 are pre-production silicon and
are no longer intended for deployment outside of ASPEED.

The existing binding and driver were written against A0 prior to the A1
rework. The A0 design directly wired INTC1 instances to INTC0, and
INTC0 to the GIC of the Primary Service Processor (PSP, a Cortex-A35).
The A0 binding and driver therefore do not account for the alternative
destinations of the Secondary and Tertiary Service Processors (SSP,
TSP) and BootMCU, or the necessary route selection logic present in the
production design.

With the above context, this series replaces the existing binding and
driver.

It is not necessary for projects to maintain support for A0 due to its
pre-production nature, and between Linux, U-Boot and Zephyr there are
no upstream devicetree users of the current binding.

The new binding uses localised interrupt numbers and models the
hardware connectivity between interrupt controllers using the
aspeed,interrupt-ranges property. It is introduced in a new file before
the existing binding is removed in order to keep the diff readable.

The INTC0 driver creates a hierarchical irqdomain under the selected
upstream interrupt controller and implements route resolution logic.
INTC1 driver instances defer route selection to INTC0 and expose a
linear interrupt namespace to their parent.

A brief history of related submissions
--------------------------------------

Some modifications to the existing binding were sent to the lists in
the past. Due to process choices the revisions were difficult to track.
They are listed below.

The approaches took several forms but ended in the minor adjustment in
v6 being applied. This enabled use of the A1 design but requires
assumptions about platform route configuration defined in firmware.
These assumptions are removed by this current series.

* [PATCH] dt-bindings: interrupt-controller: aspeed: Refine AST2700 binding description and example
  https://lore.kernel.org/all/20250714071753.2653620-1-ryan_chen@aspeedtech.com/

* [PATCH v2] dt-bindings: interrupt-controller: aspeed: Add parent node compatibles and refine documentation
  https://lore.kernel.org/all/20250715024258.2304665-1-ryan_chen@aspeedtech.com/

* [PATCH v3 0/2] irqchip: aspeed: Add AST2700 INTC debugfs support and yaml update
  https://lore.kernel.org/all/20250722095156.1672873-1-ryan_chen@aspeedtech.com/

* [PATCH v4 0/2] irqchip/ast2700-intc: Add AST2700 INTC debugfs support and yaml update
  https://lore.kernel.org/all/20250812100830.145578-1-ryan_chen@aspeedtech.com/

* [PATCH v5 0/3] AST2700 interrupt controller hierarchy support
  https://lore.kernel.org/all/20251022065507.1152071-1-ryan_chen@aspeedtech.com/

* [PATCH v6 0/1] Update correct AST2700 interrupt controller binding
  https://lore.kernel.org/all/20251030060155.2342604-1-ryan_chen@aspeedtech.com/

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
Changes in v5:
- 2/4 reduce unnecessary line breaks.
- 2/4, 3/4 fix enable CONFIG_PROVE_LOCKING irq lock inversion dependency
  detected.
- Link to v4: https://lore.kernel.org/r/20260330-irqchip-v4-0-3c0f1620cc06@aspeedtech.com

Changes in v4:
- 3/4 fix warning: the frame size of 1296 bytes is larger than 1280 bytes
- Link to v3: https://lore.kernel.org/r/20260326-irqchip-v3-0-366739f57acf@aspeedtech.com

Changes in v3:
- 1/4 Squash patch 5/5 and 1/5.
- 1/4 modify wrap lines at 80 char.
- 1/4 modify maintainers name and email.
- 1/4 modify typo Sevice-> Service
- Link to v2: https://lore.kernel.org/r/20260306-irqchip-v2-0-f8512c09be63@aspeedtech.com

Changes in v2:
- Change suject to "AST2700-A2 interrupt controller hierarchy and route
  support".
- Describe timeline for (pre-)production design evolution and
  binding development to support the break in compatibility.
- fix "make dt_binding_check" compatible string consistance with
  example.
- Split KUnit coverage out of the main driver patch.
- Link to v1: https://lore.kernel.org/r/20260205-irqchip-v1-0-b0310e06c087@aspeedtech.com

---
Ryan Chen (4):
      dt-bindings: interrupt-controller: Describe AST2700-A2 hardware instead of A0
      irqchip/ast2700-intc: Add AST2700-A2 support
      irqchip/ast2700-intc: Add KUnit tests for route resolution
      irqchip/aspeed-intc: Remove AST2700-A0 support

 .../interrupt-controller/aspeed,ast2700-intc.yaml  |  90 ----
 .../aspeed,ast2700-interrupt.yaml                  | 188 +++++++
 drivers/irqchip/.kunitconfig                       |   5 +
 drivers/irqchip/Kconfig                            |  23 +
 drivers/irqchip/Makefile                           |   3 +-
 drivers/irqchip/irq-aspeed-intc.c                  | 139 -----
 drivers/irqchip/irq-ast2700-intc0-test.c           | 473 +++++++++++++++++
 drivers/irqchip/irq-ast2700-intc0.c                | 582 +++++++++++++++++++++
 drivers/irqchip/irq-ast2700-intc1.c                | 280 ++++++++++
 drivers/irqchip/irq-ast2700.c                      | 107 ++++
 drivers/irqchip/irq-ast2700.h                      |  48 ++
 11 files changed, 1708 insertions(+), 230 deletions(-)
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260205-irqchip-7eaef3674de9

Best regards,
-- 
Ryan Chen <ryan_chen@aspeedtech.com>


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox