Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v1 1/3] dt-bindings: arm: fsl: add Variscite DART-MX8M-MINI Boards
From: Krzysztof Kozlowski @ 2026-06-11  9:06 UTC (permalink / raw)
  To: Stefano Radaelli
  Cc: linux-kernel, devicetree, imx, linux-arm-kernel, pierluigi.p,
	Stefano Radaelli, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Shawn Guo, Daniel Baluta, Dario Binacchi, Josua Mayer,
	Maud Spierings, Alexander Stein, Ernest Van Hoecke,
	Francesco Dolcini, Hugo Villeneuve
In-Reply-To: <a3355082aec3454f671b44e1f9a78000d2733470.1781024557.git.stefano.r@variscite.com>

On Wed, Jun 10, 2026 at 10:58:53AM +0200, Stefano Radaelli wrote:
> From: Stefano Radaelli <stefano.r@variscite.com>
> 
> Add DT compatible strings for Variscite DART-MX8MM SoM and Variscite
> development carrier Board.
> 
> Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
> ---
>  Documentation/devicetree/bindings/arm/fsl.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof



^ permalink raw reply

* [PATCH v7 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Kyle Hsieh @ 2026-06-11  9:06 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery
  Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
	Kyle Hsieh
In-Reply-To: <20260611-ventura2_initial_dts-v7-0-a61d8902bc5f@gmail.com>

Ventura2 is a Rack Management Controller. It is a modular
device designed to manage liquid cooling systems and monitor hardware
states within an IT rack. The system uses an AST2600 BMC for management.

RMCv2 serves several critical roles:
- Detects liquid leakage at both tray and rack levels.
- Communicates with and controls liquid cooling equipment.
- Manages leakage events and executes system recovery protocols.

Key hardware features include:
- An extensive I2C and IO expander topology to support comprehensive
  sensor monitoring and backward compatibility with legacy trays.
- MCTP over I2C support for asynchronous device communications.
- A dual-flash design for BMC firmware redundancy.

Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
 arch/arm/boot/dts/aspeed/Makefile                  |    1 +
 .../dts/aspeed/aspeed-bmc-facebook-ventura2.dts    | 2897 ++++++++++++++++++++
 2 files changed, 2898 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/Makefile b/arch/arm/boot/dts/aspeed/Makefile
index 9adf9278dc94..6b96997629d4 100644
--- a/arch/arm/boot/dts/aspeed/Makefile
+++ b/arch/arm/boot/dts/aspeed/Makefile
@@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-facebook-minipack.dtb \
 	aspeed-bmc-facebook-santabarbara.dtb \
 	aspeed-bmc-facebook-tiogapass.dtb \
+	aspeed-bmc-facebook-ventura2.dtb \
 	aspeed-bmc-facebook-wedge40.dtb \
 	aspeed-bmc-facebook-wedge100.dtb \
 	aspeed-bmc-facebook-wedge400-data64.dtb \
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts
new file mode 100644
index 000000000000..12fad349e71b
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts
@@ -0,0 +1,2897 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2023 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+	model = "Facebook Ventura2 RMC";
+	compatible = "facebook,ventura2-rmc", "aspeed,ast2600";
+	aliases {
+		serial2 = &uart3;
+		serial4 = &uart5;
+
+		/*
+		 * Pre-allocate I2C bus aliases for userspace predictability.
+		 * Several I2C channels are intentionally left empty in this DTS
+		 * as they are strictly reserved for future hardware feature expansions
+		 * and add-on boards that will interface with these busses.
+		 */
+		/*
+		 * i2c switch 0-0077, pca9548, 8 child channels assigned
+		 * with bus number 16-23.
+		 */
+		i2c16 = &i2c0mux0ch0;
+		i2c17 = &i2c0mux0ch1;
+		i2c18 = &i2c0mux0ch2;
+		i2c19 = &i2c0mux0ch3;
+		i2c20 = &i2c0mux0ch4;
+		i2c21 = &i2c0mux0ch5;
+		i2c22 = &i2c0mux0ch6;
+		i2c23 = &i2c0mux0ch7;
+
+		/*
+		 * i2c switch 1-0077, pca9548, 8 child channels assigned
+		 * with bus number 24-31.
+		 */
+		i2c24 = &i2c1mux0ch0;
+		i2c25 = &i2c1mux0ch1;
+		i2c26 = &i2c1mux0ch2;
+		i2c27 = &i2c1mux0ch3;
+		i2c28 = &i2c1mux0ch4;
+		i2c29 = &i2c1mux0ch5;
+		i2c30 = &i2c1mux0ch6;
+		i2c31 = &i2c1mux0ch7;
+
+		/*
+		 * i2c switch 4-0077, pca9548, 8 child channels assigned
+		 * with bus number 32-39.
+		 */
+		i2c32 = &i2c4mux0ch0;
+		i2c33 = &i2c4mux0ch1;
+		i2c34 = &i2c4mux0ch2;
+		i2c35 = &i2c4mux0ch3;
+		i2c36 = &i2c4mux0ch4;
+		i2c37 = &i2c4mux0ch5;
+		i2c38 = &i2c4mux0ch6;
+		i2c39 = &i2c4mux0ch7;
+
+		/*
+		 * i2c switch 5-0077, pca9548, 8 child channels assigned
+		 * with bus number 40-47.
+		 */
+		i2c40 = &i2c5mux0ch0;
+		i2c41 = &i2c5mux0ch1;
+		i2c42 = &i2c5mux0ch2;
+		i2c43 = &i2c5mux0ch3;
+		i2c44 = &i2c5mux0ch4;
+		i2c45 = &i2c5mux0ch5;
+		i2c46 = &i2c5mux0ch6;
+		i2c47 = &i2c5mux0ch7;
+
+		/*
+		 * i2c switch 8-0077, pca9548, 8 child channels assigned
+		 * with bus number 48-55.
+		 */
+		i2c48 = &i2c8mux0ch0;
+		i2c49 = &i2c8mux0ch1;
+		i2c50 = &i2c8mux0ch2;
+		i2c51 = &i2c8mux0ch3;
+		i2c52 = &i2c8mux0ch4;
+		i2c53 = &i2c8mux0ch5;
+		i2c54 = &i2c8mux0ch6;
+		i2c55 = &i2c8mux0ch7;
+
+		/*
+		 * i2c switch 11-0077, pca9548, 8 child channels assigned
+		 * with bus number 56-63.
+		 */
+		i2c56 = &i2c11mux0ch0;
+		i2c57 = &i2c11mux0ch1;
+		i2c58 = &i2c11mux0ch2;
+		i2c59 = &i2c11mux0ch3;
+		i2c60 = &i2c11mux0ch4;
+		i2c61 = &i2c11mux0ch5;
+		i2c62 = &i2c11mux0ch6;
+		i2c63 = &i2c11mux0ch7;
+
+		/*
+		 * i2c switch 13-0077, pca9548, 8 child channels assigned
+		 * with bus number 64-71.
+		 */
+		i2c64 = &i2c13mux0ch0;
+		i2c65 = &i2c13mux0ch1;
+		i2c66 = &i2c13mux0ch2;
+		i2c67 = &i2c13mux0ch3;
+		i2c68 = &i2c13mux0ch4;
+		i2c69 = &i2c13mux0ch5;
+		i2c70 = &i2c13mux0ch6;
+		i2c71 = &i2c13mux0ch7;
+
+		/*
+		 * i2c switch 15-0077, pca9548, 8 child channels assigned
+		 * with bus number 72-79.
+		 */
+		i2c72 = &i2c15mux0ch0;
+		i2c73 = &i2c15mux0ch1;
+		i2c74 = &i2c15mux0ch2;
+		i2c75 = &i2c15mux0ch3;
+		i2c76 = &i2c15mux0ch4;
+		i2c77 = &i2c15mux0ch5;
+		i2c78 = &i2c15mux0ch6;
+		i2c79 = &i2c15mux0ch7;
+	};
+
+	chosen {
+		stdout-path = "serial4:57600n8";
+	};
+
+	fan_leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			/* The 'ledd' intentionally matches the hardware schematic */
+			label = "fcb0fan0_ledd1_blue";
+			default-state = "off";
+			gpios = <&fan_io_expander0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led-1 {
+			label = "fcb0fan1_ledd2_blue";
+			default-state = "off";
+			gpios = <&fan_io_expander0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		led-2 {
+			label = "fcb0fan2_ledd3_blue";
+			default-state = "off";
+			gpios = <&fan_io_expander1 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led-3 {
+			label = "fcb0fan3_ledd4_blue";
+			default-state = "off";
+			gpios = <&fan_io_expander1 1 GPIO_ACTIVE_LOW>;
+		};
+
+		led-4 {
+			label = "fcb0fan0_ledd1_amber";
+			default-state = "off";
+			gpios = <&fan_io_expander0 4 GPIO_ACTIVE_LOW>;
+		};
+
+		led-5 {
+			label = "fcb0fan1_ledd2_amber";
+			default-state = "off";
+			gpios = <&fan_io_expander0 5 GPIO_ACTIVE_LOW>;
+		};
+
+		led-6 {
+			label = "fcb0fan2_ledd3_amber";
+			default-state = "off";
+			gpios = <&fan_io_expander1 4 GPIO_ACTIVE_LOW>;
+		};
+
+		led-7 {
+			label = "fcb0fan3_ledd4_amber";
+			default-state = "off";
+			gpios = <&fan_io_expander1 5 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+		<&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+		<&adc1 2>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			label = "bmc_heartbeat_amber";
+			gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		led-1 {
+			label = "fp_id_amber";
+			default-state = "off";
+			gpios = <&gpio0 ASPEED_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
+		};
+
+		led-2 {
+			label = "bmc_ready_noled";
+			default-state = "on";
+			gpios = <&gpio0 ASPEED_GPIO(B, 3) (GPIO_ACTIVE_HIGH|GPIO_TRANSITORY)>;
+		};
+
+		led-3 {
+			label = "power_blue";
+			default-state = "off";
+			gpios = <&gpio0 ASPEED_GPIO(P, 4) GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x80000000>;
+	};
+
+	p1v8_bmc_aux: regulator-p1v8-bmc-aux {
+		compatible = "regulator-fixed";
+		regulator-name = "p1v8_bmc_aux";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-always-on;
+	};
+
+	p2v5_bmc_aux: regulator-p2v5-bmc-aux {
+		compatible = "regulator-fixed";
+		regulator-name = "p2v5_bmc_aux";
+		regulator-min-microvolt = <2500000>;
+		regulator-max-microvolt = <2500000>;
+		regulator-always-on;
+	};
+
+	p5v_dac_aux: regulator-p5v-bmc-aux {
+		compatible = "regulator-fixed";
+		regulator-name = "p5v_dac_aux";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	spi1_gpio: spi {
+		compatible = "spi-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sck-gpios = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+		mosi-gpios = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+		miso-gpios = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>;
+		cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+		num-chipselects = <1>;
+
+		tpm@0 {
+			compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+			spi-max-frequency = <33000000>;
+			reg = <0>;
+		};
+	};
+};
+
+&adc0 {
+	vref-supply = <&p1v8_bmc_aux>;
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
+	&pinctrl_adc2_default &pinctrl_adc3_default
+	&pinctrl_adc4_default &pinctrl_adc5_default
+	&pinctrl_adc6_default &pinctrl_adc7_default>;
+};
+
+&adc1 {
+	vref-supply = <&p2v5_bmc_aux>;
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_adc8_default &pinctrl_adc10_default>;
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&fmc {
+	status = "okay";
+
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc";
+		spi-max-frequency = <50000000>;
+		#include "openbmc-flash-layout-128.dtsi"
+	};
+
+	flash@1 {
+		status = "okay";
+		m25p,fast-read;
+		label = "alt-bmc";
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&gpio0 {
+	gpio-line-names =
+	/*A0-A7*/	"","","","","","","","",
+	/*B0-B7*/	"BATTERY_DETECT","","","BMC_READY_R",
+			"","FM_ID_LED","","",
+	/*C0-C7*/	"","","","","","","","",
+	/*D0-D7*/	"","","","","","","","",
+	/*E0-E7*/	"","","","","","","","",
+	/*F0-F7*/	"","","","","","","","",
+	/*G0-G7*/	"FM_MUX1_SEL_R","","","",
+			"","","","",
+	/*H0-H7*/	"","","","","","","","",
+	/*I0-I7*/	"","","","","","","","",
+	/*J0-J7*/	"","","","","","","","",
+	/*K0-K7*/	"","","","","","","","",
+	/*L0-L7*/	"","","","","","","","",
+	/*M0-M7*/	"","","","","STBY_POWER_PG_3V3","","","",
+	/*N0-N7*/	"LED_POSTCODE_0","LED_POSTCODE_1",
+			"LED_POSTCODE_2","LED_POSTCODE_3",
+			"LED_POSTCODE_4","LED_POSTCODE_5",
+			"LED_POSTCODE_6","LED_POSTCODE_7",
+	/*O0-O7*/	"","","","","","","","debug-card-mux",
+	/*P0-P7*/	"PWR_BTN_BMC_BUF_N","","ID_RST_BTN_BMC_N","",
+			"PWR_LED","","","BMC_HEARTBEAT_N",
+	/*Q0-Q7*/	"","","","","","","","",
+	/*R0-R7*/	"","","","","","","","",
+	/*S0-S7*/	"","","SYS_BMC_PWRBTN_R_N","","","","","",
+	/*T0-T7*/	"","","","","","","","",
+	/*U0-U7*/	"","","","","","","","",
+	/*V0-V7*/	"","","","","","","","",
+	/*W0-W7*/	"","","","","","","","",
+	/*X0-X7*/	"","","","","","","","",
+	/*Y0-Y7*/	"","","","","","","","",
+	/*Z0-Z7*/	"","","","","","","","";
+};
+
+&gpio1 {
+	gpio-line-names =
+	/*18A0-18A7*/	"","","","","","","","",
+	/*18B0-18B7*/	"","","","",
+			"FM_BOARD_BMC_REV_ID0","FM_BOARD_BMC_REV_ID1",
+			"FM_BOARD_BMC_REV_ID2","",
+	/*18C0-18C7*/	"SPI_BMC_BIOS_ROM_IRQ0_R_N","","","","","","","",
+	/*18D0-18D7*/	"","","","","","","","",
+	/*18E0-18E3*/	"FM_BMC_PROT_LS_EN","AC_PWR_BMC_BTN_R_N","","";
+};
+
+&i2c0 {
+	status = "okay";
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		i2c0mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		i2c0mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		i2c0mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		i2c0mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			status = "okay";
+		};
+
+		i2c0mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			status = "okay";
+		};
+
+		i2c0mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			status = "okay";
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+
+		i2c0mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+
+			fan_io_expander0: gpio@20 {
+				compatible = "nxp,pca9555";
+				reg = <0x20>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			fan_io_expander1: gpio@21 {
+				compatible = "nxp,pca9555";
+				reg = <0x21>;
+				gpio-controller;
+				#gpio-cells = <2>;
+			};
+
+			adc@1d {
+				compatible = "ti,adc128d818";
+				reg = <0x1d>;
+				ti,mode = /bits/ 8 <1>;
+			};
+
+			adc@35 {
+				compatible = "maxim,max11617";
+				reg = <0x35>;
+			};
+		};
+
+		i2c0mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+
+			fanctl0: fan-controller@20 {
+				compatible = "maxim,max31790";
+				reg = <0x20>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				channel@2 {
+					reg = <2>;
+					sensor-type = "TACH";
+				};
+
+				channel@5 {
+					reg = <5>;
+					sensor-type = "TACH";
+				};
+			};
+
+			fanctl1: fan-controller@23 {
+				compatible = "nuvoton,nct7363";
+				reg = <0x23>;
+				#pwm-cells = <2>;
+
+				fan-0 {
+					pwms = <&fanctl1 10 20000>;
+					tach-ch = /bits/ 8 <0x00>;
+				};
+
+				fan-1 {
+					pwms = <&fanctl1 6 20000>;
+					tach-ch = /bits/ 8 <0x01>;
+				};
+
+				fan-3 {
+					pwms = <&fanctl1 10 20000>;
+					tach-ch = /bits/ 8 <0x03>;
+				};
+
+				fan-9 {
+					pwms = <&fanctl1 0 20000>;
+					tach-ch = /bits/ 8 <0x09>;
+				};
+
+				fan-10 {
+					pwms = <&fanctl1 4 20000>;
+					tach-ch = /bits/ 8 <0x0A>;
+				};
+
+				fan-11 {
+					pwms = <&fanctl1 0 20000>;
+					tach-ch = /bits/ 8 <0x0B>;
+				};
+
+				fan-13 {
+					pwms = <&fanctl1 4 20000>;
+					tach-ch = /bits/ 8 <0x0D>;
+				};
+
+				fan-15 {
+					pwms = <&fanctl1 6 20000>;
+					tach-ch = /bits/ 8 <0x0F>;
+				};
+			};
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		i2c1mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "okay";
+		};
+
+		i2c1mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "okay";
+		};
+
+		i2c1mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			status = "okay";
+		};
+
+		i2c1mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			status = "okay";
+		};
+
+		i2c1mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			status = "okay";
+		};
+
+		i2c1mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			status = "okay";
+		};
+
+		i2c1mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			status = "okay";
+		};
+
+		i2c1mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			status = "okay";
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+	bus-frequency = <400000>;
+};
+
+&i2c3 {
+	status = "okay";
+	bus-frequency = <400000>;
+
+	dac@c {
+		reg = <0x0c>;
+		compatible = "adi,ad5612";
+		vcc-supply = <&p5v_dac_aux>;
+	};
+
+	dac@e {
+		reg = <0x0e>;
+		compatible = "adi,ad5612";
+		vcc-supply = <&p5v_dac_aux>;
+	};
+
+	dac@f {
+		reg = <0x0f>;
+		compatible = "adi,ad5612";
+		vcc-supply = <&p5v_dac_aux>;
+	};
+
+	io_expander6: gpio@23 {
+		compatible = "nxp,pca9555";
+		reg = <0x23>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&io_expander7>;
+		interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	prsnt_io_expander0: gpio@40 {
+		compatible = "nxp,pca9698";
+		reg = <0x40>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <48 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN1_TRAY1_PRSNT", "CAN1_TRAY2_PRSNT",
+			"CAN1_TRAY3_PRSNT", "CAN1_TRAY4_PRSNT",
+			"CAN1_TRAY5_PRSNT", "CAN1_TRAY6_PRSNT",
+			"CAN1_TRAY7_PRSNT", "CAN1_TRAY8_PRSNT",
+			"CAN1_TRAY9_PRSNT", "CAN1_TRAY10_PRSNT",
+			"CAN1_TRAY11_PRSNT", "CAN1_TRAY12_PRSNT",
+			"CAN1_TRAY13_PRSNT", "CAN1_TRAY14_PRSNT",
+			"CAN1_TRAY15_PRSNT", "CAN1_TRAY16_PRSNT",
+			"CAN1_TRAY17_PRSNT", "CAN1_TRAY18_PRSNT",
+			"CAN1_TRAY19_PRSNT", "CAN1_TRAY20_PRSNT",
+			"CAN1_TRAY21_PRSNT", "CAN1_TRAY22_PRSNT",
+			"CAN1_TRAY23_PRSNT", "CAN1_TRAY24_PRSNT",
+			"CAN1_TRAY25_PRSNT", "CAN1_TRAY26_PRSNT",
+			"CAN1_TRAY27_PRSNT", "CAN1_TRAY28_PRSNT",
+			"CAN1_TRAY29_PRSNT", "CAN1_TRAY30_PRSNT",
+			"CAN1_TRAY31_PRSNT", "CAN1_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	prsnt_io_expander1: gpio@41 {
+		compatible = "nxp,pca9698";
+		reg = <0x41>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <56 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN2_TRAY1_PRSNT", "CAN2_TRAY2_PRSNT",
+			"CAN2_TRAY3_PRSNT", "CAN2_TRAY4_PRSNT",
+			"CAN2_TRAY5_PRSNT", "CAN2_TRAY6_PRSNT",
+			"CAN2_TRAY7_PRSNT", "CAN2_TRAY8_PRSNT",
+			"CAN2_TRAY9_PRSNT", "CAN2_TRAY10_PRSNT",
+			"CAN2_TRAY11_PRSNT", "CAN2_TRAY12_PRSNT",
+			"CAN2_TRAY13_PRSNT", "CAN2_TRAY14_PRSNT",
+			"CAN2_TRAY15_PRSNT", "CAN2_TRAY16_PRSNT",
+			"CAN2_TRAY17_PRSNT", "CAN2_TRAY18_PRSNT",
+			"CAN2_TRAY19_PRSNT", "CAN2_TRAY20_PRSNT",
+			"CAN2_TRAY21_PRSNT", "CAN2_TRAY22_PRSNT",
+			"CAN2_TRAY23_PRSNT", "CAN2_TRAY24_PRSNT",
+			"CAN2_TRAY25_PRSNT", "CAN2_TRAY26_PRSNT",
+			"CAN2_TRAY27_PRSNT", "CAN2_TRAY28_PRSNT",
+			"CAN2_TRAY29_PRSNT", "CAN2_TRAY30_PRSNT",
+			"CAN2_TRAY31_PRSNT", "CAN2_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	prsnt_io_expander2: gpio@42 {
+		compatible = "nxp,pca9698";
+		reg = <0x42>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <64 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN3_TRAY1_PRSNT", "CAN3_TRAY2_PRSNT",
+			"CAN3_TRAY3_PRSNT", "CAN3_TRAY4_PRSNT",
+			"CAN3_TRAY5_PRSNT", "CAN3_TRAY6_PRSNT",
+			"CAN3_TRAY7_PRSNT", "CAN3_TRAY8_PRSNT",
+			"CAN3_TRAY9_PRSNT", "CAN3_TRAY10_PRSNT",
+			"CAN3_TRAY11_PRSNT", "CAN3_TRAY12_PRSNT",
+			"CAN3_TRAY13_PRSNT", "CAN3_TRAY14_PRSNT",
+			"CAN3_TRAY15_PRSNT", "CAN3_TRAY16_PRSNT",
+			"CAN3_TRAY17_PRSNT", "CAN3_TRAY18_PRSNT",
+			"CAN3_TRAY19_PRSNT", "CAN3_TRAY20_PRSNT",
+			"CAN3_TRAY21_PRSNT", "CAN3_TRAY22_PRSNT",
+			"CAN3_TRAY23_PRSNT", "CAN3_TRAY24_PRSNT",
+			"CAN3_TRAY25_PRSNT", "CAN3_TRAY26_PRSNT",
+			"CAN3_TRAY27_PRSNT", "CAN3_TRAY28_PRSNT",
+			"CAN3_TRAY29_PRSNT", "CAN3_TRAY30_PRSNT",
+			"CAN3_TRAY31_PRSNT", "CAN3_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	prsnt_io_expander3: gpio@43 {
+		compatible = "nxp,pca9698";
+		reg = <0x43>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <72 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN4_TRAY1_PRSNT", "CAN4_TRAY2_PRSNT",
+			"CAN4_TRAY3_PRSNT", "CAN4_TRAY4_PRSNT",
+			"CAN4_TRAY5_PRSNT", "CAN4_TRAY6_PRSNT",
+			"CAN4_TRAY7_PRSNT", "CAN4_TRAY8_PRSNT",
+			"CAN4_TRAY9_PRSNT", "CAN4_TRAY10_PRSNT",
+			"CAN4_TRAY11_PRSNT", "CAN4_TRAY12_PRSNT",
+			"CAN4_TRAY13_PRSNT", "CAN4_TRAY14_PRSNT",
+			"CAN4_TRAY15_PRSNT", "CAN4_TRAY16_PRSNT",
+			"CAN4_TRAY17_PRSNT", "CAN4_TRAY18_PRSNT",
+			"CAN4_TRAY19_PRSNT", "CAN4_TRAY20_PRSNT",
+			"CAN4_TRAY21_PRSNT", "CAN4_TRAY22_PRSNT",
+			"CAN4_TRAY23_PRSNT", "CAN4_TRAY24_PRSNT",
+			"CAN4_TRAY25_PRSNT", "CAN4_TRAY26_PRSNT",
+			"CAN4_TRAY27_PRSNT", "CAN4_TRAY28_PRSNT",
+			"CAN4_TRAY29_PRSNT", "CAN4_TRAY30_PRSNT",
+			"CAN4_TRAY31_PRSNT", "CAN4_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	prsnt_io_expander4: gpio@44 {
+		compatible = "nxp,pca9698";
+		reg = <0x44>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <80 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN5_TRAY1_PRSNT", "CAN5_TRAY2_PRSNT",
+			"CAN5_TRAY3_PRSNT", "CAN5_TRAY4_PRSNT",
+			"CAN5_TRAY5_PRSNT", "CAN5_TRAY6_PRSNT",
+			"CAN5_TRAY7_PRSNT", "CAN5_TRAY8_PRSNT",
+			"CAN5_TRAY9_PRSNT", "CAN5_TRAY10_PRSNT",
+			"CAN5_TRAY11_PRSNT", "CAN5_TRAY12_PRSNT",
+			"CAN5_TRAY13_PRSNT", "CAN5_TRAY14_PRSNT",
+			"CAN5_TRAY15_PRSNT", "CAN5_TRAY16_PRSNT",
+			"CAN5_TRAY17_PRSNT", "CAN5_TRAY18_PRSNT",
+			"CAN5_TRAY19_PRSNT", "CAN5_TRAY20_PRSNT",
+			"CAN5_TRAY21_PRSNT", "CAN5_TRAY22_PRSNT",
+			"CAN5_TRAY23_PRSNT", "CAN5_TRAY24_PRSNT",
+			"CAN5_TRAY25_PRSNT", "CAN5_TRAY26_PRSNT",
+			"CAN5_TRAY27_PRSNT", "CAN5_TRAY28_PRSNT",
+			"CAN5_TRAY29_PRSNT", "CAN5_TRAY30_PRSNT",
+			"CAN5_TRAY31_PRSNT", "CAN5_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	prsnt_io_expander5: gpio@45 {
+		compatible = "nxp,pca9698";
+		reg = <0x45>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN6_TRAY1_PRSNT", "CAN6_TRAY2_PRSNT",
+			"CAN6_TRAY3_PRSNT", "CAN6_TRAY4_PRSNT",
+			"CAN6_TRAY5_PRSNT", "CAN6_TRAY6_PRSNT",
+			"CAN6_TRAY7_PRSNT", "CAN6_TRAY8_PRSNT",
+			"CAN6_TRAY9_PRSNT", "CAN6_TRAY10_PRSNT",
+			"CAN6_TRAY11_PRSNT", "CAN6_TRAY12_PRSNT",
+			"CAN6_TRAY13_PRSNT", "CAN6_TRAY14_PRSNT",
+			"CAN6_TRAY15_PRSNT", "CAN6_TRAY16_PRSNT",
+			"CAN6_TRAY17_PRSNT", "CAN6_TRAY18_PRSNT",
+			"CAN6_TRAY19_PRSNT", "CAN6_TRAY20_PRSNT",
+			"CAN6_TRAY21_PRSNT", "CAN6_TRAY22_PRSNT",
+			"CAN6_TRAY23_PRSNT", "CAN6_TRAY24_PRSNT",
+			"CAN6_TRAY25_PRSNT", "CAN6_TRAY26_PRSNT",
+			"CAN6_TRAY27_PRSNT", "CAN6_TRAY28_PRSNT",
+			"CAN6_TRAY29_PRSNT", "CAN6_TRAY30_PRSNT",
+			"CAN6_TRAY31_PRSNT", "CAN6_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	prsnt_io_expander6: gpio@46 {
+		compatible = "nxp,pca9698";
+		reg = <0x46>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <96 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN7_TRAY1_PRSNT", "CAN7_TRAY2_PRSNT",
+			"CAN7_TRAY3_PRSNT", "CAN7_TRAY4_PRSNT",
+			"CAN7_TRAY5_PRSNT", "CAN7_TRAY6_PRSNT",
+			"CAN7_TRAY7_PRSNT", "CAN7_TRAY8_PRSNT",
+			"CAN7_TRAY9_PRSNT", "CAN7_TRAY10_PRSNT",
+			"CAN7_TRAY11_PRSNT", "CAN7_TRAY12_PRSNT",
+			"CAN7_TRAY13_PRSNT", "CAN7_TRAY14_PRSNT",
+			"CAN7_TRAY15_PRSNT", "CAN7_TRAY16_PRSNT",
+			"CAN7_TRAY17_PRSNT", "CAN7_TRAY18_PRSNT",
+			"CAN7_TRAY19_PRSNT", "CAN7_TRAY20_PRSNT",
+			"CAN7_TRAY21_PRSNT", "CAN7_TRAY22_PRSNT",
+			"CAN7_TRAY23_PRSNT", "CAN7_TRAY24_PRSNT",
+			"CAN7_TRAY25_PRSNT", "CAN7_TRAY26_PRSNT",
+			"CAN7_TRAY27_PRSNT", "CAN7_TRAY28_PRSNT",
+			"CAN7_TRAY29_PRSNT", "CAN7_TRAY30_PRSNT",
+			"CAN7_TRAY31_PRSNT", "CAN7_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	prsnt_io_expander7: gpio@47 {
+		compatible = "nxp,pca9698";
+		reg = <0x47>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <104 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN8_TRAY1_PRSNT", "CAN8_TRAY2_PRSNT",
+			"CAN8_TRAY3_PRSNT", "CAN8_TRAY4_PRSNT",
+			"CAN8_TRAY5_PRSNT", "CAN8_TRAY6_PRSNT",
+			"CAN8_TRAY7_PRSNT", "CAN8_TRAY8_PRSNT",
+			"CAN8_TRAY9_PRSNT", "CAN8_TRAY10_PRSNT",
+			"CAN8_TRAY11_PRSNT", "CAN8_TRAY12_PRSNT",
+			"CAN8_TRAY13_PRSNT", "CAN8_TRAY14_PRSNT",
+			"CAN8_TRAY15_PRSNT", "CAN8_TRAY16_PRSNT",
+			"CAN8_TRAY17_PRSNT", "CAN8_TRAY18_PRSNT",
+			"CAN8_TRAY19_PRSNT", "CAN8_TRAY20_PRSNT",
+			"CAN8_TRAY21_PRSNT", "CAN8_TRAY22_PRSNT",
+			"CAN8_TRAY23_PRSNT", "CAN8_TRAY24_PRSNT",
+			"CAN8_TRAY25_PRSNT", "CAN8_TRAY26_PRSNT",
+			"CAN8_TRAY27_PRSNT", "CAN8_TRAY28_PRSNT",
+			"CAN8_TRAY29_PRSNT", "CAN8_TRAY30_PRSNT",
+			"CAN8_TRAY31_PRSNT", "CAN8_TRAY32_PRSNT",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander0: gpio@48 {
+		compatible = "nxp,pca9698";
+		reg = <0x48>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <50 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN1_TRAY1_PWRGD", "CAN1_TRAY2_PWRGD",
+			"CAN1_TRAY3_PWRGD", "CAN1_TRAY4_PWRGD",
+			"CAN1_TRAY5_PWRGD", "CAN1_TRAY6_PWRGD",
+			"CAN1_TRAY7_PWRGD", "CAN1_TRAY8_PWRGD",
+			"CAN1_TRAY9_PWRGD", "CAN1_TRAY10_PWRGD",
+			"CAN1_TRAY11_PWRGD", "CAN1_TRAY12_PWRGD",
+			"CAN1_TRAY13_PWRGD", "CAN1_TRAY14_PWRGD",
+			"CAN1_TRAY15_PWRGD", "CAN1_TRAY16_PWRGD",
+			"CAN1_TRAY17_PWRGD", "CAN1_TRAY18_PWRGD",
+			"CAN1_TRAY19_PWRGD", "CAN1_TRAY20_PWRGD",
+			"CAN1_TRAY21_PWRGD", "CAN1_TRAY22_PWRGD",
+			"CAN1_TRAY23_PWRGD", "CAN1_TRAY24_PWRGD",
+			"CAN1_TRAY25_PWRGD", "CAN1_TRAY26_PWRGD",
+			"CAN1_TRAY27_PWRGD", "CAN1_TRAY28_PWRGD",
+			"CAN1_TRAY29_PWRGD", "CAN1_TRAY30_PWRGD",
+			"CAN1_TRAY31_PWRGD", "CAN1_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander1: gpio@49 {
+		compatible = "nxp,pca9698";
+		reg = <0x49>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <58 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN2_TRAY1_PWRGD", "CAN2_TRAY2_PWRGD",
+			"CAN2_TRAY3_PWRGD", "CAN2_TRAY4_PWRGD",
+			"CAN2_TRAY5_PWRGD", "CAN2_TRAY6_PWRGD",
+			"CAN2_TRAY7_PWRGD", "CAN2_TRAY8_PWRGD",
+			"CAN2_TRAY9_PWRGD", "CAN2_TRAY10_PWRGD",
+			"CAN2_TRAY11_PWRGD", "CAN2_TRAY12_PWRGD",
+			"CAN2_TRAY13_PWRGD", "CAN2_TRAY14_PWRGD",
+			"CAN2_TRAY15_PWRGD", "CAN2_TRAY16_PWRGD",
+			"CAN2_TRAY17_PWRGD", "CAN2_TRAY18_PWRGD",
+			"CAN2_TRAY19_PWRGD", "CAN2_TRAY20_PWRGD",
+			"CAN2_TRAY21_PWRGD", "CAN2_TRAY22_PWRGD",
+			"CAN2_TRAY23_PWRGD", "CAN2_TRAY24_PWRGD",
+			"CAN2_TRAY25_PWRGD", "CAN2_TRAY26_PWRGD",
+			"CAN2_TRAY27_PWRGD", "CAN2_TRAY28_PWRGD",
+			"CAN2_TRAY29_PWRGD", "CAN2_TRAY30_PWRGD",
+			"CAN2_TRAY31_PWRGD", "CAN2_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander2: gpio@4a {
+		compatible = "nxp,pca9698";
+		reg = <0x4a>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <66 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN3_TRAY1_PWRGD", "CAN3_TRAY2_PWRGD",
+			"CAN3_TRAY3_PWRGD", "CAN3_TRAY4_PWRGD",
+			"CAN3_TRAY5_PWRGD", "CAN3_TRAY6_PWRGD",
+			"CAN3_TRAY7_PWRGD", "CAN3_TRAY8_PWRGD",
+			"CAN3_TRAY9_PWRGD", "CAN3_TRAY10_PWRGD",
+			"CAN3_TRAY11_PWRGD", "CAN3_TRAY12_PWRGD",
+			"CAN3_TRAY13_PWRGD", "CAN3_TRAY14_PWRGD",
+			"CAN3_TRAY15_PWRGD", "CAN3_TRAY16_PWRGD",
+			"CAN3_TRAY17_PWRGD", "CAN3_TRAY18_PWRGD",
+			"CAN3_TRAY19_PWRGD", "CAN3_TRAY20_PWRGD",
+			"CAN3_TRAY21_PWRGD", "CAN3_TRAY22_PWRGD",
+			"CAN3_TRAY23_PWRGD", "CAN3_TRAY24_PWRGD",
+			"CAN3_TRAY25_PWRGD", "CAN3_TRAY26_PWRGD",
+			"CAN3_TRAY27_PWRGD", "CAN3_TRAY28_PWRGD",
+			"CAN3_TRAY29_PWRGD", "CAN3_TRAY30_PWRGD",
+			"CAN3_TRAY31_PWRGD", "CAN3_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander3: gpio@4b {
+		compatible = "nxp,pca9698";
+		reg = <0x4b>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <74 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN4_TRAY1_PWRGD", "CAN4_TRAY2_PWRGD",
+			"CAN4_TRAY3_PWRGD", "CAN4_TRAY4_PWRGD",
+			"CAN4_TRAY5_PWRGD", "CAN4_TRAY6_PWRGD",
+			"CAN4_TRAY7_PWRGD", "CAN4_TRAY8_PWRGD",
+			"CAN4_TRAY9_PWRGD", "CAN4_TRAY10_PWRGD",
+			"CAN4_TRAY11_PWRGD", "CAN4_TRAY12_PWRGD",
+			"CAN4_TRAY13_PWRGD", "CAN4_TRAY14_PWRGD",
+			"CAN4_TRAY15_PWRGD", "CAN4_TRAY16_PWRGD",
+			"CAN4_TRAY17_PWRGD", "CAN4_TRAY18_PWRGD",
+			"CAN4_TRAY19_PWRGD", "CAN4_TRAY20_PWRGD",
+			"CAN4_TRAY21_PWRGD", "CAN4_TRAY22_PWRGD",
+			"CAN4_TRAY23_PWRGD", "CAN4_TRAY24_PWRGD",
+			"CAN4_TRAY25_PWRGD", "CAN4_TRAY26_PWRGD",
+			"CAN4_TRAY27_PWRGD", "CAN4_TRAY28_PWRGD",
+			"CAN4_TRAY29_PWRGD", "CAN4_TRAY30_PWRGD",
+			"CAN4_TRAY31_PWRGD", "CAN4_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander4: gpio@4c {
+		compatible = "nxp,pca9698";
+		reg = <0x4c>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <82 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN5_TRAY1_PWRGD", "CAN5_TRAY2_PWRGD",
+			"CAN5_TRAY3_PWRGD", "CAN5_TRAY4_PWRGD",
+			"CAN5_TRAY5_PWRGD", "CAN5_TRAY6_PWRGD",
+			"CAN5_TRAY7_PWRGD", "CAN5_TRAY8_PWRGD",
+			"CAN5_TRAY9_PWRGD", "CAN5_TRAY10_PWRGD",
+			"CAN5_TRAY11_PWRGD", "CAN5_TRAY12_PWRGD",
+			"CAN5_TRAY13_PWRGD", "CAN5_TRAY14_PWRGD",
+			"CAN5_TRAY15_PWRGD", "CAN5_TRAY16_PWRGD",
+			"CAN5_TRAY17_PWRGD", "CAN5_TRAY18_PWRGD",
+			"CAN5_TRAY19_PWRGD", "CAN5_TRAY20_PWRGD",
+			"CAN5_TRAY21_PWRGD", "CAN5_TRAY22_PWRGD",
+			"CAN5_TRAY23_PWRGD", "CAN5_TRAY24_PWRGD",
+			"CAN5_TRAY25_PWRGD", "CAN5_TRAY26_PWRGD",
+			"CAN5_TRAY27_PWRGD", "CAN5_TRAY28_PWRGD",
+			"CAN5_TRAY29_PWRGD", "CAN5_TRAY30_PWRGD",
+			"CAN5_TRAY31_PWRGD", "CAN5_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander5: gpio@4d {
+		compatible = "nxp,pca9698";
+		reg = <0x4d>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <90 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN6_TRAY1_PWRGD", "CAN6_TRAY2_PWRGD",
+			"CAN6_TRAY3_PWRGD", "CAN6_TRAY4_PWRGD",
+			"CAN6_TRAY5_PWRGD", "CAN6_TRAY6_PWRGD",
+			"CAN6_TRAY7_PWRGD", "CAN6_TRAY8_PWRGD",
+			"CAN6_TRAY9_PWRGD", "CAN6_TRAY10_PWRGD",
+			"CAN6_TRAY11_PWRGD", "CAN6_TRAY12_PWRGD",
+			"CAN6_TRAY13_PWRGD", "CAN6_TRAY14_PWRGD",
+			"CAN6_TRAY15_PWRGD", "CAN6_TRAY16_PWRGD",
+			"CAN6_TRAY17_PWRGD", "CAN6_TRAY18_PWRGD",
+			"CAN6_TRAY19_PWRGD", "CAN6_TRAY20_PWRGD",
+			"CAN6_TRAY21_PWRGD", "CAN6_TRAY22_PWRGD",
+			"CAN6_TRAY23_PWRGD", "CAN6_TRAY24_PWRGD",
+			"CAN6_TRAY25_PWRGD", "CAN6_TRAY26_PWRGD",
+			"CAN6_TRAY27_PWRGD", "CAN6_TRAY28_PWRGD",
+			"CAN6_TRAY29_PWRGD", "CAN6_TRAY30_PWRGD",
+			"CAN6_TRAY31_PWRGD", "CAN6_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander6: gpio@4e {
+		compatible = "nxp,pca9698";
+		reg = <0x4e>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <98 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN7_TRAY1_PWRGD", "CAN7_TRAY2_PWRGD",
+			"CAN7_TRAY3_PWRGD", "CAN7_TRAY4_PWRGD",
+			"CAN7_TRAY5_PWRGD", "CAN7_TRAY6_PWRGD",
+			"CAN7_TRAY7_PWRGD", "CAN7_TRAY8_PWRGD",
+			"CAN7_TRAY9_PWRGD", "CAN7_TRAY10_PWRGD",
+			"CAN7_TRAY11_PWRGD", "CAN7_TRAY12_PWRGD",
+			"CAN7_TRAY13_PWRGD", "CAN7_TRAY14_PWRGD",
+			"CAN7_TRAY15_PWRGD", "CAN7_TRAY16_PWRGD",
+			"CAN7_TRAY17_PWRGD", "CAN7_TRAY18_PWRGD",
+			"CAN7_TRAY19_PWRGD", "CAN7_TRAY20_PWRGD",
+			"CAN7_TRAY21_PWRGD", "CAN7_TRAY22_PWRGD",
+			"CAN7_TRAY23_PWRGD", "CAN7_TRAY24_PWRGD",
+			"CAN7_TRAY25_PWRGD", "CAN7_TRAY26_PWRGD",
+			"CAN7_TRAY27_PWRGD", "CAN7_TRAY28_PWRGD",
+			"CAN7_TRAY29_PWRGD", "CAN7_TRAY30_PWRGD",
+			"CAN7_TRAY31_PWRGD", "CAN7_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	pwrgd_io_expander7: gpio@4f {
+		compatible = "nxp,pca9698";
+		reg = <0x4f>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <106 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN8_TRAY1_PWRGD", "CAN8_TRAY2_PWRGD",
+			"CAN8_TRAY3_PWRGD", "CAN8_TRAY4_PWRGD",
+			"CAN8_TRAY5_PWRGD", "CAN8_TRAY6_PWRGD",
+			"CAN8_TRAY7_PWRGD", "CAN8_TRAY8_PWRGD",
+			"CAN8_TRAY9_PWRGD", "CAN8_TRAY10_PWRGD",
+			"CAN8_TRAY11_PWRGD", "CAN8_TRAY12_PWRGD",
+			"CAN8_TRAY13_PWRGD", "CAN8_TRAY14_PWRGD",
+			"CAN8_TRAY15_PWRGD", "CAN8_TRAY16_PWRGD",
+			"CAN8_TRAY17_PWRGD", "CAN8_TRAY18_PWRGD",
+			"CAN8_TRAY19_PWRGD", "CAN8_TRAY20_PWRGD",
+			"CAN8_TRAY21_PWRGD", "CAN8_TRAY22_PWRGD",
+			"CAN8_TRAY23_PWRGD", "CAN8_TRAY24_PWRGD",
+			"CAN8_TRAY25_PWRGD", "CAN8_TRAY26_PWRGD",
+			"CAN8_TRAY27_PWRGD", "CAN8_TRAY28_PWRGD",
+			"CAN8_TRAY29_PWRGD", "CAN8_TRAY30_PWRGD",
+			"CAN8_TRAY31_PWRGD", "CAN8_TRAY32_PWRGD",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander0: gpio@50 {
+		compatible = "nxp,pca9698";
+		reg = <0x50>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <54 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN1_TRAY1_LARGE_LEAK", "CAN1_TRAY2_LARGE_LEAK",
+			"CAN1_TRAY3_LARGE_LEAK", "CAN1_TRAY4_LARGE_LEAK",
+			"CAN1_TRAY5_LARGE_LEAK", "CAN1_TRAY6_LARGE_LEAK",
+			"CAN1_TRAY7_LARGE_LEAK", "CAN1_TRAY8_LARGE_LEAK",
+			"CAN1_TRAY9_LARGE_LEAK", "CAN1_TRAY10_LARGE_LEAK",
+			"CAN1_TRAY11_LARGE_LEAK", "CAN1_TRAY12_LARGE_LEAK",
+			"CAN1_TRAY13_LARGE_LEAK", "CAN1_TRAY14_LARGE_LEAK",
+			"CAN1_TRAY15_LARGE_LEAK", "CAN1_TRAY16_LARGE_LEAK",
+			"CAN1_TRAY17_LARGE_LEAK", "CAN1_TRAY18_LARGE_LEAK",
+			"CAN1_TRAY19_LARGE_LEAK", "CAN1_TRAY20_LARGE_LEAK",
+			"CAN1_TRAY21_LARGE_LEAK", "CAN1_TRAY22_LARGE_LEAK",
+			"CAN1_TRAY23_LARGE_LEAK", "CAN1_TRAY24_LARGE_LEAK",
+			"CAN1_TRAY25_LARGE_LEAK", "CAN1_TRAY26_LARGE_LEAK",
+			"CAN1_TRAY27_LARGE_LEAK", "CAN1_TRAY28_LARGE_LEAK",
+			"CAN1_TRAY29_LARGE_LEAK", "CAN1_TRAY30_LARGE_LEAK",
+			"CAN1_TRAY31_LARGE_LEAK", "CAN1_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander1: gpio@51 {
+		compatible = "nxp,pca9698";
+		reg = <0x51>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <62 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN2_TRAY1_LARGE_LEAK", "CAN2_TRAY2_LARGE_LEAK",
+			"CAN2_TRAY3_LARGE_LEAK", "CAN2_TRAY4_LARGE_LEAK",
+			"CAN2_TRAY5_LARGE_LEAK", "CAN2_TRAY6_LARGE_LEAK",
+			"CAN2_TRAY7_LARGE_LEAK", "CAN2_TRAY8_LARGE_LEAK",
+			"CAN2_TRAY9_LARGE_LEAK", "CAN2_TRAY10_LARGE_LEAK",
+			"CAN2_TRAY11_LARGE_LEAK", "CAN2_TRAY12_LARGE_LEAK",
+			"CAN2_TRAY13_LARGE_LEAK", "CAN2_TRAY14_LARGE_LEAK",
+			"CAN2_TRAY15_LARGE_LEAK", "CAN2_TRAY16_LARGE_LEAK",
+			"CAN2_TRAY17_LARGE_LEAK", "CAN2_TRAY18_LARGE_LEAK",
+			"CAN2_TRAY19_LARGE_LEAK", "CAN2_TRAY20_LARGE_LEAK",
+			"CAN2_TRAY21_LARGE_LEAK", "CAN2_TRAY22_LARGE_LEAK",
+			"CAN2_TRAY23_LARGE_LEAK", "CAN2_TRAY24_LARGE_LEAK",
+			"CAN2_TRAY25_LARGE_LEAK", "CAN2_TRAY26_LARGE_LEAK",
+			"CAN2_TRAY27_LARGE_LEAK", "CAN2_TRAY28_LARGE_LEAK",
+			"CAN2_TRAY29_LARGE_LEAK", "CAN2_TRAY30_LARGE_LEAK",
+			"CAN2_TRAY31_LARGE_LEAK", "CAN2_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander2: gpio@52 {
+		compatible = "nxp,pca9698";
+		reg = <0x52>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN3_TRAY1_LARGE_LEAK", "CAN3_TRAY2_LARGE_LEAK",
+			"CAN3_TRAY3_LARGE_LEAK", "CAN3_TRAY4_LARGE_LEAK",
+			"CAN3_TRAY5_LARGE_LEAK", "CAN3_TRAY6_LARGE_LEAK",
+			"CAN3_TRAY7_LARGE_LEAK", "CAN3_TRAY8_LARGE_LEAK",
+			"CAN3_TRAY9_LARGE_LEAK", "CAN3_TRAY10_LARGE_LEAK",
+			"CAN3_TRAY11_LARGE_LEAK", "CAN3_TRAY12_LARGE_LEAK",
+			"CAN3_TRAY13_LARGE_LEAK", "CAN3_TRAY14_LARGE_LEAK",
+			"CAN3_TRAY15_LARGE_LEAK", "CAN3_TRAY16_LARGE_LEAK",
+			"CAN3_TRAY17_LARGE_LEAK", "CAN3_TRAY18_LARGE_LEAK",
+			"CAN3_TRAY19_LARGE_LEAK", "CAN3_TRAY20_LARGE_LEAK",
+			"CAN3_TRAY21_LARGE_LEAK", "CAN3_TRAY22_LARGE_LEAK",
+			"CAN3_TRAY23_LARGE_LEAK", "CAN3_TRAY24_LARGE_LEAK",
+			"CAN3_TRAY25_LARGE_LEAK", "CAN3_TRAY26_LARGE_LEAK",
+			"CAN3_TRAY27_LARGE_LEAK", "CAN3_TRAY28_LARGE_LEAK",
+			"CAN3_TRAY29_LARGE_LEAK", "CAN3_TRAY30_LARGE_LEAK",
+			"CAN3_TRAY31_LARGE_LEAK", "CAN3_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander3: gpio@53 {
+		compatible = "nxp,pca9698";
+		reg = <0x53>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <78 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN4_TRAY1_LARGE_LEAK", "CAN4_TRAY2_LARGE_LEAK",
+			"CAN4_TRAY3_LARGE_LEAK", "CAN4_TRAY4_LARGE_LEAK",
+			"CAN4_TRAY5_LARGE_LEAK", "CAN4_TRAY6_LARGE_LEAK",
+			"CAN4_TRAY7_LARGE_LEAK", "CAN4_TRAY8_LARGE_LEAK",
+			"CAN4_TRAY9_LARGE_LEAK", "CAN4_TRAY10_LARGE_LEAK",
+			"CAN4_TRAY11_LARGE_LEAK", "CAN4_TRAY12_LARGE_LEAK",
+			"CAN4_TRAY13_LARGE_LEAK", "CAN4_TRAY14_LARGE_LEAK",
+			"CAN4_TRAY15_LARGE_LEAK", "CAN4_TRAY16_LARGE_LEAK",
+			"CAN4_TRAY17_LARGE_LEAK", "CAN4_TRAY18_LARGE_LEAK",
+			"CAN4_TRAY19_LARGE_LEAK", "CAN4_TRAY20_LARGE_LEAK",
+			"CAN4_TRAY21_LARGE_LEAK", "CAN4_TRAY22_LARGE_LEAK",
+			"CAN4_TRAY23_LARGE_LEAK", "CAN4_TRAY24_LARGE_LEAK",
+			"CAN4_TRAY25_LARGE_LEAK", "CAN4_TRAY26_LARGE_LEAK",
+			"CAN4_TRAY27_LARGE_LEAK", "CAN4_TRAY28_LARGE_LEAK",
+			"CAN4_TRAY29_LARGE_LEAK", "CAN4_TRAY30_LARGE_LEAK",
+			"CAN4_TRAY31_LARGE_LEAK", "CAN4_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander4: gpio@54 {
+		compatible = "nxp,pca9698";
+		reg = <0x54>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <86 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN5_TRAY1_LARGE_LEAK", "CAN5_TRAY2_LARGE_LEAK",
+			"CAN5_TRAY3_LARGE_LEAK", "CAN5_TRAY4_LARGE_LEAK",
+			"CAN5_TRAY5_LARGE_LEAK", "CAN5_TRAY6_LARGE_LEAK",
+			"CAN5_TRAY7_LARGE_LEAK", "CAN5_TRAY8_LARGE_LEAK",
+			"CAN5_TRAY9_LARGE_LEAK", "CAN5_TRAY10_LARGE_LEAK",
+			"CAN5_TRAY11_LARGE_LEAK", "CAN5_TRAY12_LARGE_LEAK",
+			"CAN5_TRAY13_LARGE_LEAK", "CAN5_TRAY14_LARGE_LEAK",
+			"CAN5_TRAY15_LARGE_LEAK", "CAN5_TRAY16_LARGE_LEAK",
+			"CAN5_TRAY17_LARGE_LEAK", "CAN5_TRAY18_LARGE_LEAK",
+			"CAN5_TRAY19_LARGE_LEAK", "CAN5_TRAY20_LARGE_LEAK",
+			"CAN5_TRAY21_LARGE_LEAK", "CAN5_TRAY22_LARGE_LEAK",
+			"CAN5_TRAY23_LARGE_LEAK", "CAN5_TRAY24_LARGE_LEAK",
+			"CAN5_TRAY25_LARGE_LEAK", "CAN5_TRAY26_LARGE_LEAK",
+			"CAN5_TRAY27_LARGE_LEAK", "CAN5_TRAY28_LARGE_LEAK",
+			"CAN5_TRAY29_LARGE_LEAK", "CAN5_TRAY30_LARGE_LEAK",
+			"CAN5_TRAY31_LARGE_LEAK", "CAN5_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander5: gpio@55 {
+		compatible = "nxp,pca9698";
+		reg = <0x55>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <94 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN6_TRAY1_LARGE_LEAK", "CAN6_TRAY2_LARGE_LEAK",
+			"CAN6_TRAY3_LARGE_LEAK", "CAN6_TRAY4_LARGE_LEAK",
+			"CAN6_TRAY5_LARGE_LEAK", "CAN6_TRAY6_LARGE_LEAK",
+			"CAN6_TRAY7_LARGE_LEAK", "CAN6_TRAY8_LARGE_LEAK",
+			"CAN6_TRAY9_LARGE_LEAK", "CAN6_TRAY10_LARGE_LEAK",
+			"CAN6_TRAY11_LARGE_LEAK", "CAN6_TRAY12_LARGE_LEAK",
+			"CAN6_TRAY13_LARGE_LEAK", "CAN6_TRAY14_LARGE_LEAK",
+			"CAN6_TRAY15_LARGE_LEAK", "CAN6_TRAY16_LARGE_LEAK",
+			"CAN6_TRAY17_LARGE_LEAK", "CAN6_TRAY18_LARGE_LEAK",
+			"CAN6_TRAY19_LARGE_LEAK", "CAN6_TRAY20_LARGE_LEAK",
+			"CAN6_TRAY21_LARGE_LEAK", "CAN6_TRAY22_LARGE_LEAK",
+			"CAN6_TRAY23_LARGE_LEAK", "CAN6_TRAY24_LARGE_LEAK",
+			"CAN6_TRAY25_LARGE_LEAK", "CAN6_TRAY26_LARGE_LEAK",
+			"CAN6_TRAY27_LARGE_LEAK", "CAN6_TRAY28_LARGE_LEAK",
+			"CAN6_TRAY29_LARGE_LEAK", "CAN6_TRAY30_LARGE_LEAK",
+			"CAN6_TRAY31_LARGE_LEAK", "CAN6_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander6: gpio@56 {
+		compatible = "nxp,pca9698";
+		reg = <0x56>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <102 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN7_TRAY1_LARGE_LEAK", "CAN7_TRAY2_LARGE_LEAK",
+			"CAN7_TRAY3_LARGE_LEAK", "CAN7_TRAY4_LARGE_LEAK",
+			"CAN7_TRAY5_LARGE_LEAK", "CAN7_TRAY6_LARGE_LEAK",
+			"CAN7_TRAY7_LARGE_LEAK", "CAN7_TRAY8_LARGE_LEAK",
+			"CAN7_TRAY9_LARGE_LEAK", "CAN7_TRAY10_LARGE_LEAK",
+			"CAN7_TRAY11_LARGE_LEAK", "CAN7_TRAY12_LARGE_LEAK",
+			"CAN7_TRAY13_LARGE_LEAK", "CAN7_TRAY14_LARGE_LEAK",
+			"CAN7_TRAY15_LARGE_LEAK", "CAN7_TRAY16_LARGE_LEAK",
+			"CAN7_TRAY17_LARGE_LEAK", "CAN7_TRAY18_LARGE_LEAK",
+			"CAN7_TRAY19_LARGE_LEAK", "CAN7_TRAY20_LARGE_LEAK",
+			"CAN7_TRAY21_LARGE_LEAK", "CAN7_TRAY22_LARGE_LEAK",
+			"CAN7_TRAY23_LARGE_LEAK", "CAN7_TRAY24_LARGE_LEAK",
+			"CAN7_TRAY25_LARGE_LEAK", "CAN7_TRAY26_LARGE_LEAK",
+			"CAN7_TRAY27_LARGE_LEAK", "CAN7_TRAY28_LARGE_LEAK",
+			"CAN7_TRAY29_LARGE_LEAK", "CAN7_TRAY30_LARGE_LEAK",
+			"CAN7_TRAY31_LARGE_LEAK", "CAN7_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	large_leak_io_expander7: gpio@57 {
+		compatible = "nxp,pca9698";
+		reg = <0x57>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <110 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN8_TRAY1_LARGE_LEAK", "CAN8_TRAY2_LARGE_LEAK",
+			"CAN8_TRAY3_LARGE_LEAK", "CAN8_TRAY4_LARGE_LEAK",
+			"CAN8_TRAY5_LARGE_LEAK", "CAN8_TRAY6_LARGE_LEAK",
+			"CAN8_TRAY7_LARGE_LEAK", "CAN8_TRAY8_LARGE_LEAK",
+			"CAN8_TRAY9_LARGE_LEAK", "CAN8_TRAY10_LARGE_LEAK",
+			"CAN8_TRAY11_LARGE_LEAK", "CAN8_TRAY12_LARGE_LEAK",
+			"CAN8_TRAY13_LARGE_LEAK", "CAN8_TRAY14_LARGE_LEAK",
+			"CAN8_TRAY15_LARGE_LEAK", "CAN8_TRAY16_LARGE_LEAK",
+			"CAN8_TRAY17_LARGE_LEAK", "CAN8_TRAY18_LARGE_LEAK",
+			"CAN8_TRAY19_LARGE_LEAK", "CAN8_TRAY20_LARGE_LEAK",
+			"CAN8_TRAY21_LARGE_LEAK", "CAN8_TRAY22_LARGE_LEAK",
+			"CAN8_TRAY23_LARGE_LEAK", "CAN8_TRAY24_LARGE_LEAK",
+			"CAN8_TRAY25_LARGE_LEAK", "CAN8_TRAY26_LARGE_LEAK",
+			"CAN8_TRAY27_LARGE_LEAK", "CAN8_TRAY28_LARGE_LEAK",
+			"CAN8_TRAY29_LARGE_LEAK", "CAN8_TRAY30_LARGE_LEAK",
+			"CAN8_TRAY31_LARGE_LEAK", "CAN8_TRAY32_LARGE_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander0: gpio@58 {
+		compatible = "nxp,pca9698";
+		reg = <0x58>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <52 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN1_TRAY1_SMALL_LEAK", "CAN1_TRAY2_SMALL_LEAK",
+			"CAN1_TRAY3_SMALL_LEAK", "CAN1_TRAY4_SMALL_LEAK",
+			"CAN1_TRAY5_SMALL_LEAK", "CAN1_TRAY6_SMALL_LEAK",
+			"CAN1_TRAY7_SMALL_LEAK", "CAN1_TRAY8_SMALL_LEAK",
+			"CAN1_TRAY9_SMALL_LEAK", "CAN1_TRAY10_SMALL_LEAK",
+			"CAN1_TRAY11_SMALL_LEAK", "CAN1_TRAY12_SMALL_LEAK",
+			"CAN1_TRAY13_SMALL_LEAK", "CAN1_TRAY14_SMALL_LEAK",
+			"CAN1_TRAY15_SMALL_LEAK", "CAN1_TRAY16_SMALL_LEAK",
+			"CAN1_TRAY17_SMALL_LEAK", "CAN1_TRAY18_SMALL_LEAK",
+			"CAN1_TRAY19_SMALL_LEAK", "CAN1_TRAY20_SMALL_LEAK",
+			"CAN1_TRAY21_SMALL_LEAK", "CAN1_TRAY22_SMALL_LEAK",
+			"CAN1_TRAY23_SMALL_LEAK", "CAN1_TRAY24_SMALL_LEAK",
+			"CAN1_TRAY25_SMALL_LEAK", "CAN1_TRAY26_SMALL_LEAK",
+			"CAN1_TRAY27_SMALL_LEAK", "CAN1_TRAY28_SMALL_LEAK",
+			"CAN1_TRAY29_SMALL_LEAK", "CAN1_TRAY30_SMALL_LEAK",
+			"CAN1_TRAY31_SMALL_LEAK", "CAN1_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander1: gpio@59 {
+		compatible = "nxp,pca9698";
+		reg = <0x59>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <60 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN2_TRAY1_SMALL_LEAK", "CAN2_TRAY2_SMALL_LEAK",
+			"CAN2_TRAY3_SMALL_LEAK", "CAN2_TRAY4_SMALL_LEAK",
+			"CAN2_TRAY5_SMALL_LEAK", "CAN2_TRAY6_SMALL_LEAK",
+			"CAN2_TRAY7_SMALL_LEAK", "CAN2_TRAY8_SMALL_LEAK",
+			"CAN2_TRAY9_SMALL_LEAK", "CAN2_TRAY10_SMALL_LEAK",
+			"CAN2_TRAY11_SMALL_LEAK", "CAN2_TRAY12_SMALL_LEAK",
+			"CAN2_TRAY13_SMALL_LEAK", "CAN2_TRAY14_SMALL_LEAK",
+			"CAN2_TRAY15_SMALL_LEAK", "CAN2_TRAY16_SMALL_LEAK",
+			"CAN2_TRAY17_SMALL_LEAK", "CAN2_TRAY18_SMALL_LEAK",
+			"CAN2_TRAY19_SMALL_LEAK", "CAN2_TRAY20_SMALL_LEAK",
+			"CAN2_TRAY21_SMALL_LEAK", "CAN2_TRAY22_SMALL_LEAK",
+			"CAN2_TRAY23_SMALL_LEAK", "CAN2_TRAY24_SMALL_LEAK",
+			"CAN2_TRAY25_SMALL_LEAK", "CAN2_TRAY26_SMALL_LEAK",
+			"CAN2_TRAY27_SMALL_LEAK", "CAN2_TRAY28_SMALL_LEAK",
+			"CAN2_TRAY29_SMALL_LEAK", "CAN2_TRAY30_SMALL_LEAK",
+			"CAN2_TRAY31_SMALL_LEAK", "CAN2_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander2: gpio@5a {
+		compatible = "nxp,pca9698";
+		reg = <0x5a>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <68 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN3_TRAY1_SMALL_LEAK", "CAN3_TRAY2_SMALL_LEAK",
+			"CAN3_TRAY3_SMALL_LEAK", "CAN3_TRAY4_SMALL_LEAK",
+			"CAN3_TRAY5_SMALL_LEAK", "CAN3_TRAY6_SMALL_LEAK",
+			"CAN3_TRAY7_SMALL_LEAK", "CAN3_TRAY8_SMALL_LEAK",
+			"CAN3_TRAY9_SMALL_LEAK", "CAN3_TRAY10_SMALL_LEAK",
+			"CAN3_TRAY11_SMALL_LEAK", "CAN3_TRAY12_SMALL_LEAK",
+			"CAN3_TRAY13_SMALL_LEAK", "CAN3_TRAY14_SMALL_LEAK",
+			"CAN3_TRAY15_SMALL_LEAK", "CAN3_TRAY16_SMALL_LEAK",
+			"CAN3_TRAY17_SMALL_LEAK", "CAN3_TRAY18_SMALL_LEAK",
+			"CAN3_TRAY19_SMALL_LEAK", "CAN3_TRAY20_SMALL_LEAK",
+			"CAN3_TRAY21_SMALL_LEAK", "CAN3_TRAY22_SMALL_LEAK",
+			"CAN3_TRAY23_SMALL_LEAK", "CAN3_TRAY24_SMALL_LEAK",
+			"CAN3_TRAY25_SMALL_LEAK", "CAN3_TRAY26_SMALL_LEAK",
+			"CAN3_TRAY27_SMALL_LEAK", "CAN3_TRAY28_SMALL_LEAK",
+			"CAN3_TRAY29_SMALL_LEAK", "CAN3_TRAY30_SMALL_LEAK",
+			"CAN3_TRAY31_SMALL_LEAK", "CAN3_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander3: gpio@5b {
+		compatible = "nxp,pca9698";
+		reg = <0x5b>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <76 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN4_TRAY1_SMALL_LEAK", "CAN4_TRAY2_SMALL_LEAK",
+			"CAN4_TRAY3_SMALL_LEAK", "CAN4_TRAY4_SMALL_LEAK",
+			"CAN4_TRAY5_SMALL_LEAK", "CAN4_TRAY6_SMALL_LEAK",
+			"CAN4_TRAY7_SMALL_LEAK", "CAN4_TRAY8_SMALL_LEAK",
+			"CAN4_TRAY9_SMALL_LEAK", "CAN4_TRAY10_SMALL_LEAK",
+			"CAN4_TRAY11_SMALL_LEAK", "CAN4_TRAY12_SMALL_LEAK",
+			"CAN4_TRAY13_SMALL_LEAK", "CAN4_TRAY14_SMALL_LEAK",
+			"CAN4_TRAY15_SMALL_LEAK", "CAN4_TRAY16_SMALL_LEAK",
+			"CAN4_TRAY17_SMALL_LEAK", "CAN4_TRAY18_SMALL_LEAK",
+			"CAN4_TRAY19_SMALL_LEAK", "CAN4_TRAY20_SMALL_LEAK",
+			"CAN4_TRAY21_SMALL_LEAK", "CAN4_TRAY22_SMALL_LEAK",
+			"CAN4_TRAY23_SMALL_LEAK", "CAN4_TRAY24_SMALL_LEAK",
+			"CAN4_TRAY25_SMALL_LEAK", "CAN4_TRAY26_SMALL_LEAK",
+			"CAN4_TRAY27_SMALL_LEAK", "CAN4_TRAY28_SMALL_LEAK",
+			"CAN4_TRAY29_SMALL_LEAK", "CAN4_TRAY30_SMALL_LEAK",
+			"CAN4_TRAY31_SMALL_LEAK", "CAN4_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander4: gpio@5c {
+		compatible = "nxp,pca9698";
+		reg = <0x5c>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <84 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN5_TRAY1_SMALL_LEAK", "CAN5_TRAY2_SMALL_LEAK",
+			"CAN5_TRAY3_SMALL_LEAK", "CAN5_TRAY4_SMALL_LEAK",
+			"CAN5_TRAY5_SMALL_LEAK", "CAN5_TRAY6_SMALL_LEAK",
+			"CAN5_TRAY7_SMALL_LEAK", "CAN5_TRAY8_SMALL_LEAK",
+			"CAN5_TRAY9_SMALL_LEAK", "CAN5_TRAY10_SMALL_LEAK",
+			"CAN5_TRAY11_SMALL_LEAK", "CAN5_TRAY12_SMALL_LEAK",
+			"CAN5_TRAY13_SMALL_LEAK", "CAN5_TRAY14_SMALL_LEAK",
+			"CAN5_TRAY15_SMALL_LEAK", "CAN5_TRAY16_SMALL_LEAK",
+			"CAN5_TRAY17_SMALL_LEAK", "CAN5_TRAY18_SMALL_LEAK",
+			"CAN5_TRAY19_SMALL_LEAK", "CAN5_TRAY20_SMALL_LEAK",
+			"CAN5_TRAY21_SMALL_LEAK", "CAN5_TRAY22_SMALL_LEAK",
+			"CAN5_TRAY23_SMALL_LEAK", "CAN5_TRAY24_SMALL_LEAK",
+			"CAN5_TRAY25_SMALL_LEAK", "CAN5_TRAY26_SMALL_LEAK",
+			"CAN5_TRAY27_SMALL_LEAK", "CAN5_TRAY28_SMALL_LEAK",
+			"CAN5_TRAY29_SMALL_LEAK", "CAN5_TRAY30_SMALL_LEAK",
+			"CAN5_TRAY31_SMALL_LEAK", "CAN5_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander5: gpio@5d {
+		compatible = "nxp,pca9698";
+		reg = <0x5d>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <92 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN6_TRAY1_SMALL_LEAK", "CAN6_TRAY2_SMALL_LEAK",
+			"CAN6_TRAY3_SMALL_LEAK", "CAN6_TRAY4_SMALL_LEAK",
+			"CAN6_TRAY5_SMALL_LEAK", "CAN6_TRAY6_SMALL_LEAK",
+			"CAN6_TRAY7_SMALL_LEAK", "CAN6_TRAY8_SMALL_LEAK",
+			"CAN6_TRAY9_SMALL_LEAK", "CAN6_TRAY10_SMALL_LEAK",
+			"CAN6_TRAY11_SMALL_LEAK", "CAN6_TRAY12_SMALL_LEAK",
+			"CAN6_TRAY13_SMALL_LEAK", "CAN6_TRAY14_SMALL_LEAK",
+			"CAN6_TRAY15_SMALL_LEAK", "CAN6_TRAY16_SMALL_LEAK",
+			"CAN6_TRAY17_SMALL_LEAK", "CAN6_TRAY18_SMALL_LEAK",
+			"CAN6_TRAY19_SMALL_LEAK", "CAN6_TRAY20_SMALL_LEAK",
+			"CAN6_TRAY21_SMALL_LEAK", "CAN6_TRAY22_SMALL_LEAK",
+			"CAN6_TRAY23_SMALL_LEAK", "CAN6_TRAY24_SMALL_LEAK",
+			"CAN6_TRAY25_SMALL_LEAK", "CAN6_TRAY26_SMALL_LEAK",
+			"CAN6_TRAY27_SMALL_LEAK", "CAN6_TRAY28_SMALL_LEAK",
+			"CAN6_TRAY29_SMALL_LEAK", "CAN6_TRAY30_SMALL_LEAK",
+			"CAN6_TRAY31_SMALL_LEAK", "CAN6_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander6: gpio@5e {
+		compatible = "nxp,pca9698";
+		reg = <0x5e>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <100 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN7_TRAY1_SMALL_LEAK", "CAN7_TRAY2_SMALL_LEAK",
+			"CAN7_TRAY3_SMALL_LEAK", "CAN7_TRAY4_SMALL_LEAK",
+			"CAN7_TRAY5_SMALL_LEAK", "CAN7_TRAY6_SMALL_LEAK",
+			"CAN7_TRAY7_SMALL_LEAK", "CAN7_TRAY8_SMALL_LEAK",
+			"CAN7_TRAY9_SMALL_LEAK", "CAN7_TRAY10_SMALL_LEAK",
+			"CAN7_TRAY11_SMALL_LEAK", "CAN7_TRAY12_SMALL_LEAK",
+			"CAN7_TRAY13_SMALL_LEAK", "CAN7_TRAY14_SMALL_LEAK",
+			"CAN7_TRAY15_SMALL_LEAK", "CAN7_TRAY16_SMALL_LEAK",
+			"CAN7_TRAY17_SMALL_LEAK", "CAN7_TRAY18_SMALL_LEAK",
+			"CAN7_TRAY19_SMALL_LEAK", "CAN7_TRAY20_SMALL_LEAK",
+			"CAN7_TRAY21_SMALL_LEAK", "CAN7_TRAY22_SMALL_LEAK",
+			"CAN7_TRAY23_SMALL_LEAK", "CAN7_TRAY24_SMALL_LEAK",
+			"CAN7_TRAY25_SMALL_LEAK", "CAN7_TRAY26_SMALL_LEAK",
+			"CAN7_TRAY27_SMALL_LEAK", "CAN7_TRAY28_SMALL_LEAK",
+			"CAN7_TRAY29_SMALL_LEAK", "CAN7_TRAY30_SMALL_LEAK",
+			"CAN7_TRAY31_SMALL_LEAK", "CAN7_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	small_leak_io_expander7: gpio@5f {
+		compatible = "nxp,pca9698";
+		reg = <0x5f>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <108 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"CAN8_TRAY1_SMALL_LEAK", "CAN8_TRAY2_SMALL_LEAK",
+			"CAN8_TRAY3_SMALL_LEAK", "CAN8_TRAY4_SMALL_LEAK",
+			"CAN8_TRAY5_SMALL_LEAK", "CAN8_TRAY6_SMALL_LEAK",
+			"CAN8_TRAY7_SMALL_LEAK", "CAN8_TRAY8_SMALL_LEAK",
+			"CAN8_TRAY9_SMALL_LEAK", "CAN8_TRAY10_SMALL_LEAK",
+			"CAN8_TRAY11_SMALL_LEAK", "CAN8_TRAY12_SMALL_LEAK",
+			"CAN8_TRAY13_SMALL_LEAK", "CAN8_TRAY14_SMALL_LEAK",
+			"CAN8_TRAY15_SMALL_LEAK", "CAN8_TRAY16_SMALL_LEAK",
+			"CAN8_TRAY17_SMALL_LEAK", "CAN8_TRAY18_SMALL_LEAK",
+			"CAN8_TRAY19_SMALL_LEAK", "CAN8_TRAY20_SMALL_LEAK",
+			"CAN8_TRAY21_SMALL_LEAK", "CAN8_TRAY22_SMALL_LEAK",
+			"CAN8_TRAY23_SMALL_LEAK", "CAN8_TRAY24_SMALL_LEAK",
+			"CAN8_TRAY25_SMALL_LEAK", "CAN8_TRAY26_SMALL_LEAK",
+			"CAN8_TRAY27_SMALL_LEAK", "CAN8_TRAY28_SMALL_LEAK",
+			"CAN8_TRAY29_SMALL_LEAK", "CAN8_TRAY30_SMALL_LEAK",
+			"CAN8_TRAY31_SMALL_LEAK", "CAN8_TRAY32_SMALL_LEAK",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+};
+
+&i2c4 {
+	status = "okay";
+	multi-master;
+	mctp-controller;
+
+	mctp0: mctp@10 {
+		compatible = "mctp-i2c-controller";
+		reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+	};
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		idle-state = <6>;
+
+		i2c4mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+
+			io_expander3: gpio@23 {
+				compatible = "nxp,pca9555";
+				reg = <0x23>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-parent = <&io_expander7>;
+				interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+				gpio-line-names =
+					"", "",
+					"", "RST_I2CRST_MUX1_N",
+					"RST_I2CRST_MUX2_N", "RST_I2CRST_MUX3_N",
+					"RST_I2CRST_MUX4_N", "RST_I2CRST_MUX5_N",
+					"RST_I2CRST_MUX6_N", "RST_I2CRST_MUX7_N",
+					"RST_I2CRST_MUX8_N", "",
+					"TRAY30_PWRGD_BUF_R", "TRAY31_PWRGD_BUF_R",
+					"TRAY32_PWRGD_BUF_R", "TRAY37_PWRGD_BUF_R";
+			};
+		};
+
+		i2c4mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+
+			temp-sensor@48 {
+				compatible = "ti,tmp75";
+				reg = <0x48>;
+			};
+
+			temp-sensor@4a {
+				compatible = "ti,tmp75";
+				reg = <0x4a>;
+			};
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+
+		i2c4mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			status = "okay";
+		};
+
+		i2c4mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			status = "okay";
+		};
+
+		i2c4mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			status = "okay";
+		};
+
+		i2c4mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			status = "okay";
+		};
+
+		i2c4mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			mctp-controller;
+		};
+
+		i2c4mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			status = "okay";
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	io_expander4: gpio@22 {
+		compatible = "nxp,pca9555";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&io_expander7>;
+		interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"R_COME_THERMTRIP_L", "R_PWRGD_PCH_PWROK",
+			"", "",
+			"", "",
+			"", "",
+			"", "",
+			"", "",
+			"", "TRAY38_PWRGD_BUF_R",
+			"TRAY39_PWRGD_BUF_R", "TRAY40_PWRGD_BUF_R";
+	};
+
+	io_expander5: gpio@23 {
+		compatible = "nxp,pca9555";
+		reg = <0x23>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&io_expander7>;
+		interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"PWRGD_P5V_AUX_R2", "",
+			"PWRGD_P1V5_AUX_R", "PWRGD_P1V05_AUX_R",
+			"PWRGD_P52V_HSC_PWROK_R", "PWRGD_P24V_AUX_2_R",
+			"PWRGD_P24V_AUX_R", "PWRGD_P12V_AUX_R2",
+			"PWRGD_P12V_SCM_R", "P24V_AUX_INA230_ALERT_N_R",
+			"", "PRSNT_CAN1_MCIO_N",
+			"PRSNT_CAN2_MCIO_N", "PRSNT_AALC_MCIO_N",
+			"PRSNT_RACKMON_MCIO_N", "PRSNT_RIO_RACKMON_N";
+	};
+
+	temp-sensor@4f {
+		compatible = "ti,tmp75";
+		reg = <0x4f>;
+	};
+
+	eeprom@54 {
+		compatible = "atmel,24c128";
+		reg = <0x54>;
+	};
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		i2c5mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		i2c5mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		i2c5mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+
+		i2c5mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+
+		i2c5mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+
+		i2c5mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+
+		i2c5mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+
+		i2c5mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+
+			eeprom@56 {
+				compatible = "atmel,24c128";
+				reg = <0x56>;
+			};
+		};
+	};
+};
+
+&i2c6 {
+	status = "okay";
+
+	dac@c {
+		reg = <0x0c>;
+		compatible = "adi,ad5612";
+		vcc-supply = <&p5v_dac_aux>;
+	};
+
+	dac@e {
+		reg = <0x0e>;
+		compatible = "adi,ad5612";
+		vcc-supply = <&p5v_dac_aux>;
+	};
+
+	dac@f {
+		reg = <0x0f>;
+		compatible = "adi,ad5612";
+		vcc-supply = <&p5v_dac_aux>;
+	};
+
+	io_expander0: gpio@20 {
+		compatible = "nxp,pca9555";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&io_expander7>;
+		/*
+		 * Note: io_expander0 and io_expander8 physically share the
+		 * same interrupt line (Wired-OR) to io_expander7 pin 0.
+		 */
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"", "",
+			"", "",
+			"", "PRSNT_FANBP_0_PWR_N",
+			"PRSNT_FANBP_0_SIG_N", "PRSNT_POE_PWR_N",
+			"PRSNT_POE_SIG_N", "",
+			"PWRGD_P3V3_ISO_POE_BMC_R", "",
+			"", "",
+			"DEV_DIS_N", "PCI_DIS_N";
+	};
+
+	io_expander1: gpio@21 {
+		compatible = "nxp,pca9555";
+		reg = <0x21>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&io_expander7>;
+		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"PWRGD_CPU_LVC3_BMC", "R_FM_BIOS_POST_CMPLT_BMC",
+			"", "",
+			"", "",
+			"", "",
+			"", "",
+			"", "PCIE_SSD1_PRSNT_N",
+			"", "TRAY23_PWRGD_BUF_R",
+			"TRAY24_PWRGD_BUF_R", "TRAY29_PWRGD_BUF_R";
+	};
+
+	io_expander2: gpio@22 {
+		compatible = "nxp,pca9555";
+		reg = <0x22>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&io_expander7>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"BOARD_ID_0", "BOARD_ID_1",
+			"BOARD_ID_2", "BOARD_ID_3",
+			"SKU_ID_3", "SKU_ID_2",
+			"SKU_ID_1", "SKU_ID_0",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	io_expander7: gpio@23 {
+		compatible = "nxp,pca9555";
+		reg = <0x23>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <32 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"IOEXP1_INT_N", "IOEXP2_INT_N",
+			"IOEXP3_INT_N", "IOEXP4_INT_N",
+			"IOEXP5_INT_N", "IOEXP6_INT_N",
+			"IOEXP7_INT_N", "",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	io_expander8: gpio@24 {
+		compatible = "nxp,pca9555";
+		reg = <0x24>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&io_expander7>;
+		/* Shared interrupt line with io_expander0 */
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"PRSNT_MGMT_J54_N", "PRSNT_RACKMON_J47_N",
+			"PRSNT_MGMT_DEBUG_J53_N", "PRSNT_MINISAS_TOP_J49_N",
+			"PRSNT_MINISAS_TOP_J50_N", "PRSNT_MINISAS_BOT_J51_N",
+			"PRSNT_MINISAS_BOT_J52_N", "JTAG_PLD_JTAGEN",
+			"PU_PLD_CONFIG_N", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	/* Marvell 88E6393X EEPROM */
+	eeprom@50 {
+		compatible = "atmel,24c64";
+		reg = <0x50>;
+	};
+
+	rtc@51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&i2c7 {
+	status = "okay";
+	bus-frequency = <100000>;
+	multi-master;
+	aspeed,hw-timeout-ms = <1000>;
+
+	ipmb@10 {
+		compatible = "ipmb-dev";
+		reg = <(0x10 | I2C_OWN_SLAVE_ADDRESS)>;
+		i2c-protocol;
+	};
+};
+
+&i2c8 {
+	status = "okay";
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		i2c8mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "okay";
+		};
+
+		i2c8mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "okay";
+		};
+
+		i2c8mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			status = "okay";
+		};
+
+		i2c8mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			status = "okay";
+		};
+
+		i2c8mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			status = "okay";
+		};
+
+		i2c8mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			status = "okay";
+		};
+
+		i2c8mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			status = "okay";
+		};
+
+		i2c8mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			status = "okay";
+		};
+	};
+};
+
+&i2c9 {
+	status = "okay";
+
+	temperature-sensor@4b {
+		compatible = "ti,tmp75";
+		reg = <0x4b>;
+	};
+
+	eeprom@50 {
+		compatible = "atmel,24c128";
+		reg = <0x50>;
+	};
+
+	eeprom@51 {
+		compatible = "atmel,24c128";
+		reg = <0x51>;
+	};
+
+	eeprom@56 {
+		compatible = "atmel,24c64";
+		reg = <0x56>;
+	};
+};
+
+&i2c10 {
+	status = "okay";
+	/*
+	 * This board physically routes two sets of presence signals to support
+	 * both new and older tray designs concurrently.
+	 * The 'legacy_' prefix is used to distinguish these backward-compatible
+	 * PCA9555 expanders from the new CAN-based PCA9698 expanders (e.g., gpio@40)
+	 * and to prevent device tree label collisions.
+	 */
+	legacy_prsnt_io_expander0: gpio@11 {
+		compatible = "nxp,pca9555";
+		reg = <0x11>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <40 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_PRSNT1_N_BUF_R", "TRAY_PRSNT2_N_BUF_R",
+			"TRAY_PRSNT3_N_BUF_R", "TRAY_PRSNT4_N_BUF_R",
+			"TRAY_PRSNT5_N_BUF_R", "TRAY_PRSNT6_N_BUF_R",
+			"TRAY_PRSNT7_N_BUF_R", "TRAY_PRSNT8_N_BUF_R",
+			"TRAY_PRSNT9_N_BUF_R", "TRAY_PRSNT10_N_BUF_R",
+			"TRAY_PRSNT11_N_BUF_R", "TRAY_PRSNT12_N_BUF_R",
+			"TRAY_PRSNT13_N_BUF_R", "TRAY_PRSNT14_N_BUF_R",
+			"TRAY_PRSNT15_N_BUF_R", "TRAY_PRSNT16_N_BUF_R";
+	};
+
+	legacy_prsnt_io_expander1: gpio@12 {
+		compatible = "nxp,pca9555";
+		reg = <0x12>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <40 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_PRSNT17_N_BUF_R", "TRAY_PRSNT18_N_BUF_R",
+			"TRAY_PRSNT19_N_BUF_R", "TRAY_PRSNT20_N_BUF_R",
+			"TRAY_PRSNT21_N_BUF_R", "TRAY_PRSNT22_N_BUF_R",
+			"TRAY_PRSNT23_N_BUF_R", "TRAY_PRSNT24_N_BUF_R",
+			"TRAY_PRSNT25_N_BUF_R", "TRAY_PRSNT26_N_BUF_R",
+			"TRAY_PRSNT27_N_BUF_R", "TRAY_PRSNT28_N_BUF_R",
+			"TRAY_PRSNT29_N_BUF_R", "TRAY_PRSNT30_N_BUF_R",
+			"TRAY_PRSNT31_N_BUF_R", "TRAY_PRSNT32_N_BUF_R";
+	};
+
+	legacy_prsnt_io_expander2: gpio@13 {
+		compatible = "nxp,pca9555";
+		reg = <0x13>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <40 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_PRSNT33_N_BUF_R", "TRAY_PRSNT34_N_BUF_R",
+			"TRAY_PRSNT35_N_BUF_R", "TRAY_PRSNT36_N_BUF_R",
+			"TRAY_PRSNT37_N_BUF_R", "TRAY_PRSNT38_N_BUF_R",
+			"TRAY_PRSNT39_N_BUF_R", "TRAY_PRSNT40_N_BUF_R",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	power-monitor@14 {
+		compatible = "infineon,xdp710";
+		reg = <0x14>;
+	};
+
+	legacy_pwrgd_io_expander1: gpio@15 {
+		compatible = "nxp,pca9555";
+		reg = <0x15>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <42 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_PWRGD17_N_BUF_R", "TRAY_PWRGD18_N_BUF_R",
+			"TRAY_PWRGD19_N_BUF_R", "TRAY_PWRGD20_N_BUF_R",
+			"TRAY_PWRGD21_N_BUF_R", "TRAY_PWRGD22_N_BUF_R",
+			"TRAY_PWRGD23_N_BUF_R", "TRAY_PWRGD24_N_BUF_R",
+			"TRAY_PWRGD25_N_BUF_R", "TRAY_PWRGD26_N_BUF_R",
+			"TRAY_PWRGD27_N_BUF_R", "TRAY_PWRGD28_N_BUF_R",
+			"TRAY_PWRGD29_N_BUF_R", "TRAY_PWRGD30_N_BUF_R",
+			"TRAY_PWRGD31_N_BUF_R", "TRAY_PWRGD32_N_BUF_R";
+	};
+
+	legacy_pwrgd_io_expander2: gpio@16 {
+		compatible = "nxp,pca9555";
+		reg = <0x16>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <42 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_PWRGD33_N_BUF_R", "TRAY_PWRGD34_N_BUF_R",
+			"TRAY_PWRGD35_N_BUF_R", "TRAY_PWRGD36_N_BUF_R",
+			"TRAY_PWRGD37_N_BUF_R", "TRAY_PWRGD38_N_BUF_R",
+			"TRAY_PWRGD39_N_BUF_R", "TRAY_PWRGD40_N_BUF_R",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	legacy_leak_io_expander0: gpio@17 {
+		compatible = "nxp,pca9555";
+		reg = <0x17>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <46 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_LEAK_DETECT1_N_BUF_R", "TRAY_LEAK_DETECT2_N_BUF_R",
+			"TRAY_LEAK_DETECT3_N_BUF_R", "TRAY_LEAK_DETECT4_N_BUF_R",
+			"TRAY_LEAK_DETECT5_N_BUF_R", "TRAY_LEAK_DETECT6_N_BUF_R",
+			"TRAY_LEAK_DETECT7_N_BUF_R", "TRAY_LEAK_DETECT8_N_BUF_R",
+			"TRAY_LEAK_DETECT9_N_BUF_R", "TRAY_LEAK_DETECT10_N_BUF_R",
+			"TRAY_LEAK_DETECT11_N_BUF_R", "TRAY_LEAK_DETECT12_N_BUF_R",
+			"TRAY_LEAK_DETECT13_N_BUF_R", "TRAY_LEAK_DETECT14_N_BUF_R",
+			"TRAY_LEAK_DETECT15_N_BUF_R", "TRAY_LEAK_DETECT16_N_BUF_R";
+	};
+
+	legacy_leak_io_expander1: gpio@18 {
+		compatible = "nxp,pca9555";
+		reg = <0x18>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <46 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_LEAK_DETECT17_N_BUF_R", "TRAY_LEAK_DETECT18_N_BUF_R",
+			"TRAY_LEAK_DETECT19_N_BUF_R", "TRAY_LEAK_DETECT20_N_BUF_R",
+			"TRAY_LEAK_DETECT21_N_BUF_R", "TRAY_LEAK_DETECT22_N_BUF_R",
+			"TRAY_LEAK_DETECT23_N_BUF_R", "TRAY_LEAK_DETECT24_N_BUF_R",
+			"TRAY_LEAK_DETECT25_N_BUF_R", "TRAY_LEAK_DETECT26_N_BUF_R",
+			"TRAY_LEAK_DETECT27_N_BUF_R", "TRAY_LEAK_DETECT28_N_BUF_R",
+			"TRAY_LEAK_DETECT29_N_BUF_R", "TRAY_LEAK_DETECT30_N_BUF_R",
+			"TRAY_LEAK_DETECT31_N_BUF_R", "TRAY_LEAK_DETECT32_N_BUF_R";
+	};
+
+	legacy_leak_io_expander2: gpio@19 {
+		compatible = "nxp,pca9555";
+		reg = <0x19>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <46 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_LEAK_DETECT33_N_BUF_R", "TRAY_LEAK_DETECT34_N_BUF_R",
+			"TRAY_LEAK_DETECT35_N_BUF_R", "TRAY_LEAK_DETECT36_N_BUF_R",
+			"TRAY_LEAK_DETECT37_N_BUF_R", "TRAY_LEAK_DETECT38_N_BUF_R",
+			"TRAY_LEAK_DETECT39_N_BUF_R", "TRAY_LEAK_DETECT40_N_BUF_R",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	legacy_small_leak_io_expander0: gpio@1a {
+		compatible = "nxp,pca9555";
+		reg = <0x1a>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <44 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_SMALL_LEAK1_N_BUF_R", "TRAY_SMALL_LEAK2_N_BUF_R",
+			"TRAY_SMALL_LEAK3_N_BUF_R", "TRAY_SMALL_LEAK4_N_BUF_R",
+			"TRAY_SMALL_LEAK5_N_BUF_R", "TRAY_SMALL_LEAK6_N_BUF_R",
+			"TRAY_SMALL_LEAK7_N_BUF_R", "TRAY_SMALL_LEAK8_N_BUF_R",
+			"TRAY_SMALL_LEAK9_N_BUF_R", "TRAY_SMALL_LEAK10_N_BUF_R",
+			"TRAY_SMALL_LEAK11_N_BUF_R", "TRAY_SMALL_LEAK12_N_BUF_R",
+			"TRAY_SMALL_LEAK13_N_BUF_R", "TRAY_SMALL_LEAK14_N_BUF_R",
+			"TRAY_SMALL_LEAK15_N_BUF_R", "TRAY_SMALL_LEAK16_N_BUF_R";
+	};
+
+	legacy_small_leak_io_expander1: gpio@1b {
+		compatible = "nxp,pca9555";
+		reg = <0x1b>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <44 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_SMALL_LEAK17_N_BUF_R", "TRAY_SMALL_LEAK18_N_BUF_R",
+			"TRAY_SMALL_LEAK19_N_BUF_R", "TRAY_SMALL_LEAK20_N_BUF_R",
+			"TRAY_SMALL_LEAK21_N_BUF_R", "TRAY_SMALL_LEAK22_N_BUF_R",
+			"TRAY_SMALL_LEAK23_N_BUF_R", "TRAY_SMALL_LEAK24_N_BUF_R",
+			"TRAY_SMALL_LEAK25_N_BUF_R", "TRAY_SMALL_LEAK26_N_BUF_R",
+			"TRAY_SMALL_LEAK27_N_BUF_R", "TRAY_SMALL_LEAK28_N_BUF_R",
+			"TRAY_SMALL_LEAK29_N_BUF_R", "TRAY_SMALL_LEAK30_N_BUF_R",
+			"TRAY_SMALL_LEAK31_N_BUF_R", "TRAY_SMALL_LEAK32_N_BUF_R";
+	};
+
+	legacy_small_leak_io_expander2: gpio@1c {
+		compatible = "nxp,pca9555";
+		reg = <0x1c>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <44 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_SMALL_LEAK33_N_BUF_R", "TRAY_SMALL_LEAK34_N_BUF_R",
+			"TRAY_SMALL_LEAK35_N_BUF_R", "TRAY_SMALL_LEAK36_N_BUF_R",
+			"TRAY_SMALL_LEAK37_N_BUF_R", "TRAY_SMALL_LEAK38_N_BUF_R",
+			"TRAY_SMALL_LEAK39_N_BUF_R", "TRAY_SMALL_LEAK40_N_BUF_R",
+			"", "",
+			"", "",
+			"", "",
+			"", "";
+	};
+
+	legacy_pwrgd_io_expander0: gpio@28 {
+		compatible = "nxp,pca9555";
+		reg = <0x28>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&sgpiom0>;
+		interrupts = <42 IRQ_TYPE_LEVEL_LOW>;
+
+		gpio-line-names =
+			"TRAY_PWRGD1_N_BUF_R", "TRAY_PWRGD2_N_BUF_R",
+			"TRAY_PWRGD3_N_BUF_R", "TRAY_PWRGD4_N_BUF_R",
+			"TRAY_PWRGD5_N_BUF_R", "TRAY_PWRGD6_N_BUF_R",
+			"TRAY_PWRGD7_N_BUF_R", "TRAY_PWRGD8_N_BUF_R",
+			"TRAY_PWRGD9_N_BUF_R", "TRAY_PWRGD10_N_BUF_R",
+			"TRAY_PWRGD11_N_BUF_R", "TRAY_PWRGD12_N_BUF_R",
+			"TRAY_PWRGD13_N_BUF_R", "TRAY_PWRGD14_N_BUF_R",
+			"TRAY_PWRGD15_N_BUF_R", "TRAY_PWRGD16_N_BUF_R";
+	};
+
+	adc@35 {
+		compatible = "maxim,max11617";
+		reg = <0x35>;
+	};
+
+	power-monitor@44 {
+		compatible = "lltc,ltc4287";
+		reg = <0x44>;
+		shunt-resistor-micro-ohms = <500>;
+	};
+
+	adc@48 {
+		compatible = "ti,ads1015";
+		reg = <0x48>;
+	};
+
+	temp-sensor@4c {
+		compatible = "ti,tmp75";
+		reg = <0x4c>;
+	};
+
+	temp-sensor@4d {
+		compatible = "ti,tmp75";
+		reg = <0x4d>;
+	};
+
+	temp-sensor@4e {
+		compatible = "ti,tmp75";
+		reg = <0x4e>;
+	};
+
+	power-monitor@4f {
+		compatible = "ti,ina230";
+		reg = <0x4f>;
+		shunt-resistor = <1000>;
+	};
+
+	power-monitor@69 {
+		compatible = "pmbus";
+		reg = <0x69>;
+	};
+
+	fpga_io_expander64: gpio@64 {
+		compatible = "nxp,pca9555";
+		reg = <0x64>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio-line-names =
+			"", "",
+			"", "",
+			"", "",
+			"LEAK_CONFIG0", "LEAK_CONFIG1",
+			"FPGA_PWRGD_P24V_AUX_R", "FPGA_PWRGD_P24V_AUX_2_R",
+			"FPGA_PWRGD_P12V_SCM_R", "FPGA_PWRGD_P12V_AUX_R2",
+			"FPGA_PRSNT_FANBP_0_SIG_R_PLD_N", "FPGA_PRSNT_FANBP_0_PWR_R_PLD_N",
+			"FPGA_P24V_AUX_INA230_ALERT_N_R", "FPGA_SMB_TMC75_TEMP_ALERT_N_R";
+	};
+
+	fpga_io_expander65: gpio@65 {
+		compatible = "nxp,pca9555";
+		reg = <0x65>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio-line-names =
+			"FPGA_PCI_DIS_N", "FPGA_DEV_DIS_N",
+			"FPGA_PWRGD_P3V3_AUX_R", "FPGA_PWRGD_P5V_AUX_R2",
+			"FPGA_PWRGD_P1V05_AUX_R", "FPGA_P48V_HSC_ALERT_N",
+			"FPGA_PWRGD_P1V5_AUX_R", "FPGA_PWRGD_P52V_HSC_PWROK_R",
+			"FPGA_R_COME_THERMTRIP_L", "FPGA_PRSNT_POE_SIG_PLD_N",
+			"FPGA_PRSNT_POE_PWR_PLD_N", "FPGA_PRSNT_RIO_RACKMON_N",
+			"FPGA_PRSNT_CAN2_MCIO_N", "FPGA_PRSNT_CAN1_MCIO_N",
+			"FPGA_PRSNT_RACKMON_MCIO_N", "FPGA_PRSNT_AALC_MCIO_N";
+	};
+
+	fpga_io_expander66: gpio@66 {
+		compatible = "nxp,pca9555";
+		reg = <0x66>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio-line-names =
+			"FPGA_R_FM_CPU_ERR0_LVT3_L", "FPGA_FPGA_R_FM_PCHHOT_L",
+			"FPGA_R_FM_BIOS_POST_CMPLT_L", "FPGA_R_FM_SOC_BMC_RST_L",
+			"FPGA_R_CPU_MSMI_CATERR_N", "FPGA_R_H_MEMHOT_OUT_FET_L",
+			"FPGA_R_PWRGD_P3V3_STBY", "FPGA_R_PWRGD_PCH_PWROK",
+			"FPGA_TRAY23_PWRGD_BUF_R", "FPGA_TRAY24_PWRGD_BUF_R",
+			"FPGA_P24V_AUX_2_INA230_ALERT_N_R", "FPGA_R_IRQ_BMC_PCH_SMI_N",
+			"FPGA_R_FM_CPU_DIMM_EVENT_COD_BUF", "FPGA_R_BIOS_MSG_DIS_L",
+			"FPGA_R_ISO_FM_USB_OC0_L", "FPGA_SPI_LVC_EN";
+	};
+
+	fpga_io_expander67: gpio@67 {
+		compatible = "nxp,pca9555";
+		reg = <0x67>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio-line-names =
+			"FPGA_TRAY29_PWRGD_BUF_R", "FPGA_TRAY30_PWRGD_BUF_R",
+			"FPGA_TRAY31_PWRGD_BUF_R", "FPGA_TRAY32_PWRGD_BUF_R",
+			"FPGA_TRAY37_PWRGD_BUF_R", "FPGA_TRAY38_PWRGD_BUF_R",
+			"FPGA_TRAY39_PWRGD_BUF_R", "FPGA_TRAY40_PWRGD_BUF_R",
+			"FPGA_ISO_CARRIER_BOARD_PWR_OK", "FPGA_UART_MUX_SEL",
+			"", "",
+			"", "",
+			"", "";
+	};
+};
+
+&i2c11 {
+	status = "okay";
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		i2c11mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "okay";
+		};
+
+		i2c11mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "okay";
+		};
+
+		i2c11mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			status = "okay";
+		};
+
+		i2c11mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			status = "okay";
+		};
+
+		i2c11mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			status = "okay";
+		};
+
+		i2c11mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			status = "okay";
+		};
+
+		i2c11mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			status = "okay";
+		};
+
+		i2c11mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			status = "okay";
+		};
+	};
+};
+
+&i2c12 {
+	status = "okay";
+	bus-frequency = <400000>;
+};
+
+&i2c13 {
+	status = "okay";
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		i2c13mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "okay";
+		};
+
+		i2c13mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "okay";
+		};
+
+		i2c13mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			status = "okay";
+		};
+
+		i2c13mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			status = "okay";
+		};
+
+		i2c13mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			status = "okay";
+		};
+
+		i2c13mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			status = "okay";
+		};
+
+		i2c13mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			status = "okay";
+		};
+
+		i2c13mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			status = "okay";
+		};
+	};
+};
+
+&i2c14 {
+	status = "okay";
+};
+
+&i2c15 {
+	status = "okay";
+
+	i2c-mux@77 {
+		compatible = "nxp,pca9548";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		i2c-mux-idle-disconnect;
+
+		i2c15mux0ch0: i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+			status = "okay";
+		};
+
+		i2c15mux0ch1: i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			status = "okay";
+		};
+
+		i2c15mux0ch2: i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			status = "okay";
+		};
+
+		i2c15mux0ch3: i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+			status = "okay";
+		};
+
+		i2c15mux0ch4: i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+			status = "okay";
+		};
+
+		i2c15mux0ch5: i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+			status = "okay";
+		};
+
+		i2c15mux0ch6: i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+			status = "okay";
+		};
+
+		i2c15mux0ch7: i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+			status = "okay";
+		};
+	};
+};
+
+&kcs3 {
+	aspeed,lpc-io-reg = <0xca2>;
+	status = "okay";
+};
+
+&lpc_ctrl {
+	status = "okay";
+};
+
+&mac2 {
+	status = "okay";
+	phy-mode = "rmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii3_default>;
+
+	/*
+	 * The Marvell 88E6393X is initialized at boot via EEPROM
+	 * configuration and hardware straps.
+	 * The BMC connects via an RMII fixed-link; link parameters are fixed
+	 * by board design.
+	 */
+	fixed-link {
+		speed = <100>;
+		full-duplex;
+	};
+};
+
+&mac3 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rmii4_default>;
+	use-ncsi;
+};
+
+&peci0 {
+	status = "okay";
+};
+
+&sgpiom0 {
+	status = "okay";
+	ngpios = <128>;
+	bus-frequency = <100000>;
+	gpio-line-names =
+		/*"input pin","output pin"*/
+		/*A0 - A7*/
+		"power-chassis-good","FM_PLD_HEARTBEAT_LVC3_R",
+		"host0-ready","R_BMC_PTH_RST_BTN_L",
+		"CONTROL_VT2_SUPPLY1_CLOSE","FM_MDIO_SW_SEL_PLD",
+		"CONTROL_VT2_SUPPLY2_CLOSE","FM_88E6393X_BIN_UPDATE_EN_N",
+		"CONTROL_VT2_SUPPLY3_CLOSE","Sequence_TransFR_Alert",
+		"RETURN_CNTL1_FB","WATER_VALVE1_OPEN",
+		"RETURN_CNTL2_FB","WATER_VALVE2_OPEN",
+		"RETURN_CNTL3_FB","WATER_VALVE3_OPEN",
+		/*B0 - B7*/
+		"IT_STOP_PUMP_R_CPLD","WATER_VALVE1_CLOSE",
+		"IT_STOP_PUMP_SPARE_R_CPLD","WATER_VALVE2_CLOSE",
+		"IT_STOP_PUMP_2_R_CPLD","WATER_VALVE3_CLOSE",
+		"IT_STOP_PUMP_SPARE_2_R_CPLD","REPORT_VT2_SUPPLY1_CLOSE",
+		"RPU_2_READY_SPARE_PLD_R","REPORT_VT2_SUPPLY2_CLOSE",
+		"RPU_2_READY_PLD_R","REPORT_VT2_SUPPLY3_CLOSE",
+		"RPU_READY_SPARE_PLD_R","PCIE_SSD1_PRSNT_N",
+		"RPU_READY_PLD_R","",
+		/*C0 - C7*/
+		"IOEXP8_INT_N","",
+		"SUPPLY_CNTL1_FB","",
+		"SUPPLY_CNTL2_FB","",
+		"SUPPLY_CNTL3_FB","",
+		"PRSNT_TRAY1_TO_40_R_BUF_N","",
+		"PWRGD_TRAY1_TO_40_R_BUF","",
+		"SMALL_LEAK_TRAY1_TO_40_R_BUF_N","",
+		"LEAK_DETECT_TRAY1_TO_40_R_BUF_N","",
+		/*D0 - D7*/
+		"PRSNT_CANBUSP1_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP1_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP1_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP1_TRAY1_TO_32_N","",
+		"PRSNT_CANBUSP2_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP2_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP2_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP2_TRAY1_TO_32_N","",
+		/*E0 - E7*/
+		"PRSNT_CANBUSP3_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP3_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP3_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP3_TRAY1_TO_32_N","",
+		"PRSNT_CANBUSP4_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP4_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP4_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP4_TRAY1_TO_32_N","",
+		/*F0 - F7*/
+		"PRSNT_CANBUSP5_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP5_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP5_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP5_TRAY1_TO_32_N","",
+		"PRSNT_CANBUSP6_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP6_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP6_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP6_TRAY1_TO_32_N","",
+		/*G0 - G7*/
+		"PRSNT_CANBUSP7_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP7_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP7_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP7_TRAY1_TO_32_N","",
+		"PRSNT_CANBUSP8_TRAY1_TO_32_N","",
+		"PWRGD_CANBUSP8_TRAY1_TO_32_PWROK","",
+		"SMALL_LEAK_CANBUSP8_TRAY1_TO_32_N","",
+		"LEAK_DETECT_CANBUSP8_TRAY1_TO_32_N","",
+		/*H0 - H7*/
+		"CHASSIS0_LEAK_Q_N_R","",
+		"CHASSIS1_LEAK_Q_N_R","",
+		"CHASSIS2_LEAK_Q_N_R","",
+		"CHASSIS3_LEAK_Q_N_R","",
+		"CHASSIS4_LEAK_Q_N_R","",
+		"CHASSIS5_LEAK_Q_N_R","",
+		"CHASSIS6_LEAK_Q_N_R","",
+		"CHASSIS7_LEAK_Q_N_R","",
+		/*I0 - I7*/
+		"CHASSIS8_LEAK_Q_N_R","",
+		"CHASSIS9_LEAK_Q_N_R","",
+		"CHASSIS10_LEAK_Q_N_R","",
+		"CHASSIS11_LEAK_Q_N_R","",
+		"AALC_RPU_READY","",
+		"","",
+		"","",
+		"","",
+		/*J0 - J7*/
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		/*K0 - K7*/
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		"","",
+		/*L0 - L7*/
+		"IT_GEAR_RPU_2_LINK_PRSNT_SPARE_N_R","",
+		"IT_GEAR_RPU_2_LINK_PRSNT_N_R","",
+		"IT_GEAR_RPU_LINK_PRSNT_SPARE_N_R","",
+		"IT_GEAR_RPU_LINK_PRSNT_N_R","",
+		"","",
+		"","",
+		"","",
+		"","",
+		/*M0 - M7*/
+		"","",
+		"","",
+		"PRSNT_SENSOR_N","",
+		"PRSNT3_VT2_PLD_N","",
+		"PRSNT2_VT2_PLD_N","",
+		"PRSNT1_VT2_PLD_N","",
+		"PRSNT3_RETURN_PLD_N","",
+		"PRSNT2_RETURN_PLD_N","",
+		/*N0 - N7*/
+		"PRSNT1_RETURN_PLD_N","",
+		"PRSNT3_SUPPLY_PLD_N","",
+		"PRSNT2_SUPPLY_PLD_N","",
+		"PRSNT1_SUPPLY_PLD_N","",
+		"PRSNT_LEAK11_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK10_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK9_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK8_SENSOR_R_PLD_N","",
+		/*O0 - O7*/
+		"PRSNT_LEAK7_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK6_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK5_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK4_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK3_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK2_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK1_SENSOR_R_PLD_N","",
+		"PRSNT_LEAK0_SENSOR_R_PLD_N","",
+		/*P0 - P7*/
+		"","",
+		"","",
+		"","",
+		"","",
+		"","SGPIO_REG_VALID_0",
+		"","SGPIO_REG_VALID_1",
+		"","SGPIO_REG_VALID_2",
+		"","SGPIO_REG_VALID_3";
+};
+
+&spi2 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi2_default &pinctrl_spi2cs1_default>;
+
+	flash@0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "pnor";
+		spi-max-frequency = <12000000>;
+		spi-tx-bus-width = <2>;
+		spi-rx-bus-width = <2>;
+	};
+
+	flash@1 {
+		status = "okay";
+		m25p,fast-read;
+		label = "e810";
+		spi-max-frequency = <12000000>;
+		spi-tx-bus-width = <2>;
+		spi-rx-bus-width = <2>;
+	};
+};
+
+&uart3 {
+	status = "okay";
+};
+
+&wdt1 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdtrst1_default>;
+	aspeed,reset-type = "soc";
+	aspeed,external-signal;
+	aspeed,ext-push-pull;
+	aspeed,ext-active-high;
+	aspeed,ext-pulse-duration = <256>;
+};
+

-- 
2.34.1



^ permalink raw reply related

* [PATCH v7 1/2] dt-bindings: arm: aspeed: add Meta ventura2 board
From: Kyle Hsieh @ 2026-06-11  9:06 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery
  Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
	Kyle Hsieh, Krzysztof Kozlowski
In-Reply-To: <20260611-ventura2_initial_dts-v7-0-a61d8902bc5f@gmail.com>

Document the new compatibles used on Facebook ventura2.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
 Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 9298c1a75dd1..d48607c86e8e 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -92,6 +92,7 @@ properties:
               - facebook,harma-bmc
               - facebook,minerva-cmc
               - facebook,santabarbara-bmc
+              - facebook,ventura2-rmc
               - facebook,yosemite4-bmc
               - facebook,yosemite5-bmc
               - ibm,balcones-bmc

-- 
2.34.1



^ permalink raw reply related

* [PATCH v7 0/2] Add Meta(Facebook) ventura2 BMC(AST2600)
From: Kyle Hsieh @ 2026-06-11  9:06 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery
  Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
	Kyle Hsieh, Krzysztof Kozlowski

Summary:
Add linux device tree entry related to Meta(Facebook) ventura2.
specific devices connected to BMC(AST2600) SoC.

Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
Changes in v7:
- Updated the commit message to include a detailed description of the Ventura2 platform's purpose and its key hardware features.
- Fix comments from Andrew Jeffery:
  * Ensured consistent blank lines to separate child nodes from parent properties and from each other throughout the DTS.
  * Sorted fan nodes in ascending order.
  * Replaced '//' comments with '/* */' block comments.
- Fix feedback from Sashiko AI:
  * Added 'idle-state = <6>;' to the PCA9548 mux on i2c4. 
- Link to v6: https://lore.kernel.org/r/20260610-ventura2_initial_dts-v6-0-375d8e9d7ebf@gmail.com

Changes in v6:
- Addressed automated feedback from Sashiko bot:
  * Clarified comments that io_expander0 and io_expander8 physically share the same interrupt line (Wired-OR) by hardware design.
  * Removed leading zeros from unit addresses in DAC nodes (dac@c, dac@e, dac@f).
  * Removed unused properties from the adc@48 node.
- Link to v5: https://lore.kernel.org/r/20260608-ventura2_initial_dts-v5-0-37ee5bcf58b6@gmail.com

Changes in v5:
- Addressed review comments:
  * Added comments explaining the necessity of 'legacy_' prefixes (hardware label collision), pre-allocated I2C aliases (future expansions), and the 'ledd1' naming convention (schematic alignment).
  * Removed the empty `&mdio0` node to comply with upstream networking subsystem guidelines.
  * Removed the redundant `&peci0` node.
  * Sorted `&kcs3` and `&lpc_ctrl` nodes in strict alphabetical order.
- Hardware/DT alignment updates:
  * Removed unpopulated sensors (adi,adt7461, infineon,tda38640, ti,ina230, ti,ina238) to accurately reflect the current board population.
  * Added the secondary flash node (flash@1 labeled "e810") under the &spi2 bus.
- Link to v4: https://lore.kernel.org/r/20260424-ventura2_initial_dts-v4-0-806b00ea4314@gmail.com

Changes in v4:
- Fixed capitalization: "ventura2" -> "Ventura2".
- Reordered I2C child nodes in ascending order of unit addresses.
- Enable PECI, LPC control, and KCS3 interfaces for host communication.
- Configure MCTP controller on I2C4 and enable MCTP support for specific mux channels.
- Add Infineon TDA38640 and TI INA230 power monitor nodes.
- GPIO and Pinmux cleanup for PVT:
    - Aligned gpio-line-names as requested.
    - Remove unused or non-existent GPIO line names to align with Ventura2 PVT.
    - Update specific GPIO pins to empty strings where signals were removed or consolidated.
- Adjust SGPIOM frequency to 200kHz and update signal line names.
- Enable UART3 and add serial2 alias.
- Link to v3: https://lore.kernel.org/r/20260113-ventura2_initial_dts-v3-0-2dbfda6a5b47@gmail.com

Changes in v3:
- Add annotation for marvel 88e6393x
- Modify the gpio-line-name
- Modify the node order alphabetically
- Modify dt-bindings document for rmc instead of bmc
- Move the gpio-line-names to original node
- Link to v2: https://lore.kernel.org/r/20251224-ventura2_initial_dts-v2-0-f193ba5d4073@gmail.com

Changes in v2:
- Remove unused mdio
- Link to v1: https://lore.kernel.org/r/20251222-ventura2_initial_dts-v1-0-1f06166c78a3@gmail.com

---
Kyle Hsieh (2):
      dt-bindings: arm: aspeed: add Meta ventura2 board
      ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC

 .../devicetree/bindings/arm/aspeed/aspeed.yaml     |    1 +
 arch/arm/boot/dts/aspeed/Makefile                  |    1 +
 .../dts/aspeed/aspeed-bmc-facebook-ventura2.dts    | 2897 ++++++++++++++++++++
 3 files changed, 2899 insertions(+)
---
base-commit: 9448598b22c50c8a5bb77a9103e2d49f134c9578
change-id: 20251222-ventura2_initial_dts-909b3277d665

Best regards,
-- 
Kyle Hsieh <kylehsieh1995@gmail.com>



^ permalink raw reply

* Re: [PATCH v7 4/8] perf cs-etm: Use thread-stack for last branch entries
From: James Clark @ 2026-06-11  9:01 UTC (permalink / raw)
  To: Leo Yan
  Cc: linux-arm-kernel, coresight, linux-perf-users,
	Arnaldo Carvalho de Melo, John Garry, Will Deacon, Mike Leach,
	Suzuki K Poulose, Namhyung Kim, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Ian Rogers, Adrian Hunter, Al Grant, Paschalis Mpeis,
	Amir Ayupov
In-Reply-To: <20260611-b4-arm_cs_callchain_support_v1-v7-4-1ba770c862ae@arm.com>



On 11/06/2026 8:56 am, Leo Yan wrote:
> CS ETM maintains its own circular array for last branch entries, with
> local helpers to update, copy and reset the branch stack. This
> duplicates logic already provided by the common code.
> 
> Record taken branches with thread_stack__event() and synthesize
> PERF_SAMPLE_BRANCH_STACK data with thread_stack__br_sample(). This
> removes the private last_branch_rb buffer and its position tracking.
> 
> This also makes the branch history state belong to the thread rather
> than the trace queue. That is a better fit for CoreSight traces where
> a trace queue can effectively be CPU scoped, while call/return history
> is per thread.
> 
> Keep the buffer number updated via thread_stack__set_trace_nr(), which
> is used when exporting samples to Python scripts. Pass callstack=false
> for now; synthesized callchains are added by a later patch.
> 
> The output should remain same, except that be->flags.predicted is no
> longer set. Since CoreSight trace does not provide branch prediction
> information, clearing the flag avoids confusion.
> 
> Signed-off-by: Leo Yan <leo.yan@arm.com>


Reviewed-by: James Clark <james.clark@linaro.org>

> ---
>   tools/perf/util/cs-etm.c | 159 ++++++++++++++---------------------------------
>   1 file changed, 46 insertions(+), 113 deletions(-)
> 
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 4127120459418389ca7aabb9a49dead2b50e7533..8798bf0471faf3b1813780b45c588263ff6b4416 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -84,10 +84,9 @@ struct cs_etm_auxtrace {
>   struct cs_etm_traceid_queue {
>   	u8 trace_chan_id;
>   	u64 period_instructions;
> -	size_t last_branch_pos;
>   	union perf_event *event_buf;
> +	unsigned int br_stack_sz;
>   	struct branch_stack *last_branch;
> -	struct branch_stack *last_branch_rb;
>   	struct cs_etm_packet *prev_packet;
>   	struct cs_etm_packet *packet;
>   	struct cs_etm_packet_queue packet_queue;
> @@ -644,9 +643,8 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
>   		tidq->last_branch = zalloc(sz);
>   		if (!tidq->last_branch)
>   			goto out_free;
> -		tidq->last_branch_rb = zalloc(sz);
> -		if (!tidq->last_branch_rb)
> -			goto out_free;
> +
> +		tidq->br_stack_sz = etm->synth_opts.last_branch_sz;
>   	}
>   
>   	tidq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE);
> @@ -656,7 +654,6 @@ static int cs_etm__init_traceid_queue(struct cs_etm_queue *etmq,
>   	return 0;
>   
>   out_free:
> -	zfree(&tidq->last_branch_rb);
>   	zfree(&tidq->last_branch);
>   	zfree(&tidq->prev_packet);
>   	zfree(&tidq->packet);
> @@ -939,7 +936,6 @@ static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq)
>   		thread__zput(tidq->decode_thread);
>   		zfree(&tidq->event_buf);
>   		zfree(&tidq->last_branch);
> -		zfree(&tidq->last_branch_rb);
>   		zfree(&tidq->prev_packet);
>   		zfree(&tidq->packet);
>   		zfree(&tidq);
> @@ -1299,57 +1295,6 @@ static int cs_etm__queue_first_cs_timestamp(struct cs_etm_auxtrace *etm,
>   	return ret;
>   }
>   
> -static inline
> -void cs_etm__copy_last_branch_rb(struct cs_etm_queue *etmq,
> -				 struct cs_etm_traceid_queue *tidq)
> -{
> -	struct branch_stack *bs_src = tidq->last_branch_rb;
> -	struct branch_stack *bs_dst = tidq->last_branch;
> -	size_t nr = 0;
> -
> -	/*
> -	 * Set the number of records before early exit: ->nr is used to
> -	 * determine how many branches to copy from ->entries.
> -	 */
> -	bs_dst->nr = bs_src->nr;
> -
> -	/*
> -	 * Early exit when there is nothing to copy.
> -	 */
> -	if (!bs_src->nr)
> -		return;
> -
> -	/*
> -	 * As bs_src->entries is a circular buffer, we need to copy from it in
> -	 * two steps.  First, copy the branches from the most recently inserted
> -	 * branch ->last_branch_pos until the end of bs_src->entries buffer.
> -	 */
> -	nr = etmq->etm->synth_opts.last_branch_sz - tidq->last_branch_pos;
> -	memcpy(&bs_dst->entries[0],
> -	       &bs_src->entries[tidq->last_branch_pos],
> -	       sizeof(struct branch_entry) * nr);
> -
> -	/*
> -	 * If we wrapped around at least once, the branches from the beginning
> -	 * of the bs_src->entries buffer and until the ->last_branch_pos element
> -	 * are older valid branches: copy them over.  The total number of
> -	 * branches copied over will be equal to the number of branches asked by
> -	 * the user in last_branch_sz.
> -	 */
> -	if (bs_src->nr >= etmq->etm->synth_opts.last_branch_sz) {
> -		memcpy(&bs_dst->entries[nr],
> -		       &bs_src->entries[0],
> -		       sizeof(struct branch_entry) * tidq->last_branch_pos);
> -	}
> -}
> -
> -static inline
> -void cs_etm__reset_last_branch_rb(struct cs_etm_traceid_queue *tidq)
> -{
> -	tidq->last_branch_pos = 0;
> -	tidq->last_branch_rb->nr = 0;
> -}
> -
>   static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq,
>   					 struct cs_etm_traceid_queue *tidq,
>   					 struct cs_etm_packet *packet, u64 addr)
> @@ -1419,38 +1364,6 @@ static inline u64 cs_etm__instr_addr(struct cs_etm_queue *etmq,
>   	return addr;
>   }
>   
> -static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq,
> -					  struct cs_etm_traceid_queue *tidq)
> -{
> -	struct branch_stack *bs = tidq->last_branch_rb;
> -	struct branch_entry *be;
> -
> -	/*
> -	 * The branches are recorded in a circular buffer in reverse
> -	 * chronological order: we start recording from the last element of the
> -	 * buffer down.  After writing the first element of the stack, move the
> -	 * insert position back to the end of the buffer.
> -	 */
> -	if (!tidq->last_branch_pos)
> -		tidq->last_branch_pos = etmq->etm->synth_opts.last_branch_sz;
> -
> -	tidq->last_branch_pos -= 1;
> -
> -	be       = &bs->entries[tidq->last_branch_pos];
> -	be->from = cs_etm__last_executed_instr(tidq->prev_packet);
> -	be->to	 = cs_etm__first_executed_instr(tidq->packet);
> -	/* No support for mispredict */
> -	be->flags.mispred = 0;
> -	be->flags.predicted = 1;
> -
> -	/*
> -	 * Increment bs->nr until reaching the number of last branches asked by
> -	 * the user on the command line.
> -	 */
> -	if (bs->nr < etmq->etm->synth_opts.last_branch_sz)
> -		bs->nr += 1;
> -}
> -
>   static int cs_etm__inject_event(struct cs_etm_auxtrace *etm, union perf_event *event,
>   			       struct perf_sample *sample, u64 type)
>   {
> @@ -1614,6 +1527,42 @@ static inline u64 cs_etm__resolve_sample_time(struct cs_etm_queue *etmq,
>   		return etm->latest_kernel_timestamp;
>   }
>   
> +static bool cs_etm__packet_has_taken_branch(struct cs_etm_packet *packet)
> +{
> +	if (packet->sample_type == CS_ETM_RANGE &&
> +	    packet->last_instr_taken_branch)
> +		return true;
> +
> +	return false;
> +}
> +
> +static void cs_etm__add_stack_event(struct cs_etm_queue *etmq,
> +				    struct cs_etm_traceid_queue *tidq)
> +{
> +	u64 from, to;
> +	int size;
> +
> +	if (!cs_etm__packet_has_taken_branch(tidq->prev_packet))
> +		return;
> +
> +	if (etmq->etm->synth_opts.last_branch) {
> +		from = cs_etm__last_executed_instr(tidq->prev_packet);
> +		to = cs_etm__first_executed_instr(tidq->packet);
> +
> +		size = cs_etm__instr_size(etmq, tidq, tidq->prev_packet, from);
> +
> +		/* Enable callchain so thread stack entry can be allocated */
> +		thread_stack__event(tidq->frontend_thread, tidq->prev_packet->cpu,
> +				    tidq->prev_packet->flags, from, to, size,
> +				    etmq->buffer->buffer_nr + 1, false,
> +				    tidq->br_stack_sz, 0);
> +	} else {
> +		thread_stack__set_trace_nr(tidq->frontend_thread,
> +					   tidq->prev_packet->cpu,
> +					   etmq->buffer->buffer_nr + 1);
> +	}
> +}
> +
>   static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
>   					    struct cs_etm_traceid_queue *tidq,
>   					    struct cs_etm_packet *packet,
> @@ -1644,8 +1593,11 @@ static int cs_etm__synth_instruction_sample(struct cs_etm_queue *etmq,
>   
>   	cs_etm__copy_insn(etmq, tidq, packet, &sample);
>   
> -	if (etm->synth_opts.last_branch)
> +	if (etm->synth_opts.last_branch) {
> +		thread_stack__br_sample(tidq->frontend_thread, tidq->packet->cpu,
> +					tidq->last_branch, tidq->br_stack_sz);
>   		sample.branch_stack = tidq->last_branch;
> +	}
>   
>   	if (etm->synth_opts.inject) {
>   		ret = cs_etm__inject_event(etm, event, &sample,
> @@ -1836,14 +1788,7 @@ static int cs_etm__sample(struct cs_etm_queue *etmq,
>   
>   	tidq->period_instructions += tidq->packet->instr_count;
>   
> -	/*
> -	 * Record a branch when the last instruction in
> -	 * PREV_PACKET is a branch.
> -	 */
> -	if (etm->synth_opts.last_branch &&
> -	    tidq->prev_packet->sample_type == CS_ETM_RANGE &&
> -	    tidq->prev_packet->last_instr_taken_branch)
> -		cs_etm__update_last_branch_rb(etmq, tidq);
> +	cs_etm__add_stack_event(etmq, tidq);
>   
>   	if (etm->synth_opts.instructions &&
>   	    tidq->period_instructions >= etm->instructions_sample_period) {
> @@ -1902,10 +1847,6 @@ static int cs_etm__sample(struct cs_etm_queue *etmq,
>   		u64 offset = etm->instructions_sample_period - instrs_prev;
>   		u64 addr;
>   
> -		/* Prepare last branches for instruction sample */
> -		if (etm->synth_opts.last_branch)
> -			cs_etm__copy_last_branch_rb(etmq, tidq);
> -
>   		while (tidq->period_instructions >=
>   				etm->instructions_sample_period) {
>   			/*
> @@ -1936,8 +1877,7 @@ static int cs_etm__sample(struct cs_etm_queue *etmq,
>   			generate_sample = true;
>   
>   		/* Generate sample for branch taken packet */
> -		if (tidq->prev_packet->sample_type == CS_ETM_RANGE &&
> -		    tidq->prev_packet->last_instr_taken_branch)
> +		if (cs_etm__packet_has_taken_branch(tidq->prev_packet))
>   			generate_sample = true;
>   
>   		if (generate_sample) {
> @@ -1985,10 +1925,6 @@ static int cs_etm__flush(struct cs_etm_queue *etmq,
>   	    etmq->etm->synth_opts.instructions &&
>   	    tidq->prev_packet->sample_type == CS_ETM_RANGE) {
>   		u64 addr;
> -
> -		/* Prepare last branches for instruction sample */
> -		cs_etm__copy_last_branch_rb(etmq, tidq);
> -
>   		/*
>   		 * Generate a last branch event for the branches left in the
>   		 * circular buffer at the end of the trace.
> @@ -2020,7 +1956,7 @@ static int cs_etm__flush(struct cs_etm_queue *etmq,
>   
>   	/* Reset last branches after flush the trace */
>   	if (etm->synth_opts.last_branch)
> -		cs_etm__reset_last_branch_rb(tidq);
> +		thread_stack__flush(tidq->frontend_thread);
>   
>   	return err;
>   }
> @@ -2044,9 +1980,6 @@ static int cs_etm__end_block(struct cs_etm_queue *etmq,
>   	    tidq->prev_packet->sample_type == CS_ETM_RANGE) {
>   		u64 addr;
>   
> -		/* Prepare last branches for instruction sample */
> -		cs_etm__copy_last_branch_rb(etmq, tidq);
> -
>   		/*
>   		 * Use the address of the end of the last reported execution
>   		 * range.
> 



^ permalink raw reply

* Re: [PATCH v7 1/8] perf cs-etm: Filter synthesized branch samples
From: James Clark @ 2026-06-11  8:58 UTC (permalink / raw)
  To: Leo Yan
  Cc: linux-arm-kernel, coresight, linux-perf-users, Leo Yan,
	Arnaldo Carvalho de Melo, John Garry, Will Deacon, Mike Leach,
	Suzuki K Poulose, Namhyung Kim, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Ian Rogers, Adrian Hunter, Al Grant, Paschalis Mpeis,
	Amir Ayupov
In-Reply-To: <20260611-b4-arm_cs_callchain_support_v1-v7-1-1ba770c862ae@arm.com>



On 11/06/2026 8:56 am, Leo Yan wrote:
> From: Leo Yan <leo.yan@linaro.org>
> 
> The itrace 'c' and 'r' options request synthesized branch events for
> calls and returns only. For perf script the default itrace options are
> "--itrace=ce", so CS ETM should emit call branches and error events by
> default.

You need to update test_arm_coresight_disasm.sh to pass --itrace=b for 
both tests now because it needs every branch, not just calls. Should 
probably update the documentation and examples in arm-cs-trace-disasm.py 
too.

With that,

Reviewed-by: James Clark <james.clark@linaro.org>

> 
> CS ETM currently synthesizes a branch sample for every decoded taken
> branch whenever branch synthesis is enabled. This produces redundant
> jump and conditional branch samples.
> 
> Add a branch filter derived from the itrace calls and returns options.
> When neither option is set, keep the existing behavior and synthesize all
> branch samples. When calls or returns are requested, emit only branch
> samples whose flags match the selected branch type, while preserving trace
> begin/end markers.
> 
> Before:
> 
>    perf script -F,+flags
> 
>    callchain_test    6114 [005] 331519.825214:          1 branches:   tr strt jmp                           0 [unknown] ([unknown]) => ffff8000803a3a68 perf_report_aux_output_id+0x50 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff8000803a3a74 perf_report_aux_output_id+0x5c ([kernel.kallsyms]) => ffff8000817f4d88 memset+0x0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jmp                    ffff8000817f4d8c memset+0x4 ([kernel.kallsyms]) => ffff8000817f4c00 __pi_memset_generic+0x0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000817f4c1c __pi_memset_generic+0x1c ([kernel.kallsyms]) => ffff8000817f4c44 __pi_memset_generic+0x44 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000817f4c4c __pi_memset_generic+0x4c ([kernel.kallsyms]) => ffff8000817f4c5c __pi_memset_generic+0x5c ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000817f4c5c __pi_memset_generic+0x5c ([kernel.kallsyms]) => ffff8000817f4cf0 __pi_memset_generic+0xf0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000817f4d30 __pi_memset_generic+0x130 ([kernel.kallsyms]) => ffff8000817f4d68 __pi_memset_generic+0x168 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   return                 ffff8000817f4d84 __pi_memset_generic+0x184 ([kernel.kallsyms]) => ffff8000803a3a78 perf_report_aux_output_id+0x60 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   jcc                    ffff8000803a3a98 perf_report_aux_output_id+0x80 ([kernel.kallsyms]) => ffff8000803a3b04 perf_report_aux_output_id+0xec ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff8000803a3b1c perf_report_aux_output_id+0x104 ([kernel.kallsyms]) => ffff8000803a38f8 __perf_event_header__init_id+0x0 ([kernel.kallsyms])
> 
> After:
> 
>    callchain_test    6114 [005] 331519.825214:          1 branches:   tr strt jmp                           0 [unknown] ([unknown]) => ffff8000803a3a68 perf_report_aux_output_id+0x50 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff8000803a3a74 perf_report_aux_output_id+0x5c ([kernel.kallsyms]) => ffff8000817f4d88 memset+0x0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff8000803a3b1c perf_report_aux_output_id+0x104 ([kernel.kallsyms]) => ffff8000803a38f8 __perf_event_header__init_id+0x0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff8000803a39c0 __perf_event_header__init_id+0xc8 ([kernel.kallsyms]) => ffff800080105258 __task_pid_nr_ns+0x0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff80008010528c __task_pid_nr_ns+0x34 ([kernel.kallsyms]) => ffff8000801d5610 __rcu_read_lock+0x0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff8000801052b0 __task_pid_nr_ns+0x58 ([kernel.kallsyms]) => ffff800080192078 lock_acquire+0x0 ([kernel.kallsyms])
>    callchain_test    6114 [005] 331519.825214:          1 branches:   call                   ffff8000801923f4 lock_acquire+0x37c ([kernel.kallsyms]) => ffff8000801d6da0 rcu_is_watching+0x0 ([kernel.kallsyms])
> 
> Fixes: b12235b113cf ("perf tools: Add mechanic to synthesise CoreSight trace packets")
> Signed-off-by: Leo Yan <leo.yan@linaro.org>
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
>   tools/perf/util/cs-etm.c | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
> 
> diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
> index 5e92359f51a7cb87a26866ae71466fcce809d551..c2b0f98ceee7671d0e98cfe5673c6f4ec19707a5 100644
> --- a/tools/perf/util/cs-etm.c
> +++ b/tools/perf/util/cs-etm.c
> @@ -70,6 +70,7 @@ struct cs_etm_auxtrace {
>   	int num_cpu;
>   	u64 latest_kernel_timestamp;
>   	u32 auxtrace_type;
> +	u32 branches_filter;
>   	u64 branches_sample_type;
>   	u64 branches_id;
>   	u64 instructions_sample_type;
> @@ -1681,6 +1682,10 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq,
>   	} dummy_bs;
>   	u64 ip;
>   
> +	if (etm->branches_filter &&
> +		!(etm->branches_filter & tidq->prev_packet->flags))
> +		return 0;
> +
>   	ip = cs_etm__last_executed_instr(tidq->prev_packet);
>   
>   	event->sample.header.type = PERF_RECORD_SAMPLE;
> @@ -3517,6 +3522,16 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
>   		etm->synth_opts.callchain = false;
>   	}
>   
> +	if (etm->synth_opts.calls)
> +		etm->branches_filter |= PERF_IP_FLAG_CALL |
> +					PERF_IP_FLAG_TRACE_BEGIN |
> +					PERF_IP_FLAG_TRACE_END;
> +
> +	if (etm->synth_opts.returns)
> +		etm->branches_filter |= PERF_IP_FLAG_RETURN |
> +					PERF_IP_FLAG_TRACE_BEGIN |
> +					PERF_IP_FLAG_TRACE_END;
> +
>   	etm->session = session;
>   
>   	etm->num_cpu = num_cpu;
> 



^ permalink raw reply

* [PATCH 5/5] ARM: dts: stm32: reorder mdma1 node in stm32mp15*-scmi.dts
From: Amelie Delaunay @ 2026-06-11  8:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
	Alexandre Torgue
  Cc: devicetree, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay
In-Reply-To: <20260611-node_reordering-v1-0-7e519f2cb456@foss.st.com>

In the ST board DTS files, the &label entries must be ordered
alphanumerically.
The nodes became misordered when mlahb was replaced by m4_rproc.

Move mdma1 to the right place to avoid future misordering.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts | 8 ++++----
 arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts | 8 ++++----
 arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts | 8 ++++----
 arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts | 8 ++++----
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
index 847b360f02fc..53e40e2f776b 100644
--- a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
@@ -51,10 +51,6 @@ &iwdg2 {
 	clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>;
 };
 
-&mdma1 {
-	resets = <&scmi_reset RST_SCMI_MDMA>;
-};
-
 &m4_rproc {
 	/delete-property/ st,syscfg-holdboot;
 	resets = <&scmi_reset RST_SCMI_MCU>,
@@ -62,6 +58,10 @@ &m4_rproc {
 	reset-names = "mcu_rst", "hold_boot";
 };
 
+&mdma1 {
+	resets = <&scmi_reset RST_SCMI_MDMA>;
+};
+
 &optee {
 	interrupt-parent = <&intc>;
 	interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
diff --git a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
index 43280289759d..0790ed426ebc 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
@@ -57,10 +57,6 @@ &iwdg2 {
 	clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>;
 };
 
-&mdma1 {
-	resets = <&scmi_reset RST_SCMI_MDMA>;
-};
-
 &m4_rproc {
 	/delete-property/ st,syscfg-holdboot;
 	resets = <&scmi_reset RST_SCMI_MCU>,
@@ -68,6 +64,10 @@ &m4_rproc {
 	reset-names = "mcu_rst", "hold_boot";
 };
 
+&mdma1 {
+	resets = <&scmi_reset RST_SCMI_MDMA>;
+};
+
 &optee {
 	interrupt-parent = <&intc>;
 	interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
index 6f27d794d270..0a3894aff4ae 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
@@ -56,10 +56,6 @@ &iwdg2 {
 	clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>;
 };
 
-&mdma1 {
-	resets = <&scmi_reset RST_SCMI_MDMA>;
-};
-
 &m4_rproc {
 	/delete-property/ st,syscfg-holdboot;
 	resets = <&scmi_reset RST_SCMI_MCU>,
@@ -67,6 +63,10 @@ &m4_rproc {
 	reset-names = "mcu_rst", "hold_boot";
 };
 
+&mdma1 {
+	resets = <&scmi_reset RST_SCMI_MDMA>;
+};
+
 &optee {
 	interrupt-parent = <&intc>;
 	interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
index 6ae391bffee5..c2b6efb1cbb7 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
@@ -61,10 +61,6 @@ &m_can1 {
 	clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>;
 };
 
-&mdma1 {
-	resets = <&scmi_reset RST_SCMI_MDMA>;
-};
-
 &m4_rproc {
 	/delete-property/ st,syscfg-holdboot;
 	resets = <&scmi_reset RST_SCMI_MCU>,
@@ -72,6 +68,10 @@ &m4_rproc {
 	reset-names = "mcu_rst", "hold_boot";
 };
 
+&mdma1 {
+	resets = <&scmi_reset RST_SCMI_MDMA>;
+};
+
 &optee {
 	interrupt-parent = <&intc>;
 	interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;

-- 
2.43.0



^ permalink raw reply related

* [PATCH 3/5] ARM: dts: stm32: reorder cs_cti_trace node in stm32mp15xx-dkx.dtsi
From: Amelie Delaunay @ 2026-06-11  8:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
	Alexandre Torgue
  Cc: devicetree, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay
In-Reply-To: <20260611-node_reordering-v1-0-7e519f2cb456@foss.st.com>

In the ST board DTS files, the &label entries must be ordered
alphanumerically.
The nodes became misordered when Coresight support was added.

Move cs_cti_trace to the right place to avoid future misordering.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi
index 599ea07bdb19..956509cef321 100644
--- a/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi
@@ -155,15 +155,15 @@ &crc1 {
 	status = "okay";
 };
 
-&cs_cti_trace {
+&cs_cti_cpu0 {
 	status = "okay";
 };
 
-&cs_cti_cpu0 {
+&cs_cti_cpu1 {
 	status = "okay";
 };
 
-&cs_cti_cpu1 {
+&cs_cti_trace {
 	status = "okay";
 };
 

-- 
2.43.0



^ permalink raw reply related

* [PATCH 4/5] ARM: dts: stm32: reorder cs_cti_trace node in stm32mp157c-ev1.dts
From: Amelie Delaunay @ 2026-06-11  8:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
	Alexandre Torgue
  Cc: devicetree, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay
In-Reply-To: <20260611-node_reordering-v1-0-7e519f2cb456@foss.st.com>

In the ST board DTS files, the &label entries must be ordered
alphanumerically.
The nodes became misordered when Coresight support was added.

Move cs_cti_trace to the right place to avoid future misordering.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp157c-ev1.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1.dts
index 0e65a1862eb5..eaab09e1755f 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ev1.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ev1.dts
@@ -81,15 +81,15 @@ &cec {
 	status = "okay";
 };
 
-&cs_cti_trace {
+&cs_cti_cpu0 {
 	status = "okay";
 };
 
-&cs_cti_cpu0 {
+&cs_cti_cpu1 {
 	status = "okay";
 };
 
-&cs_cti_cpu1 {
+&cs_cti_trace {
 	status = "okay";
 };
 

-- 
2.43.0



^ permalink raw reply related

* [PATCH 1/5] arm64: dts: st: reorder ommanager node in stm32mp257f-ev1.dts
From: Amelie Delaunay @ 2026-06-11  8:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
	Alexandre Torgue
  Cc: devicetree, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay
In-Reply-To: <20260611-node_reordering-v1-0-7e519f2cb456@foss.st.com>

In the ST board DTS files, the &label entries must be ordered
alphanumerically.
The nodes became misordered when &ommanager and &lptimer3 were added
simultaneouly. After that, &ltdc and &lvds used the &lptimers position
as a reference.

Move ommanager at the right place to avoid future misordering.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts | 56 +++++++++++++++---------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
index 14e033f365e3..f044331b8b55 100644
--- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
+++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -307,34 +307,6 @@ &i2c8 {
 	/delete-property/dma-names;
 };
 
-&ommanager {
-	memory-region = <&mm_ospi1>;
-	memory-region-names = "ospi1";
-	pinctrl-0 = <&ospi_port1_clk_pins_a
-		     &ospi_port1_io03_pins_a
-		     &ospi_port1_cs0_pins_a>;
-	pinctrl-1 = <&ospi_port1_clk_sleep_pins_a
-		     &ospi_port1_io03_sleep_pins_a
-		     &ospi_port1_cs0_sleep_pins_a>;
-	pinctrl-names = "default", "sleep";
-	status = "okay";
-
-	spi@0 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		memory-region = <&mm_ospi1>;
-		status = "okay";
-
-		flash0: flash@0 {
-			compatible = "jedec,spi-nor";
-			reg = <0>;
-			spi-rx-bus-width = <4>;
-			spi-tx-bus-width = <4>;
-			spi-max-frequency = <50000000>;
-		};
-	};
-};
-
 /* use LPTIMER with tick broadcast for suspend mode */
 &lptimer3 {
 	status = "okay";
@@ -374,6 +346,34 @@ lvds_out0: endpoint {
 	};
 };
 
+&ommanager {
+	memory-region = <&mm_ospi1>;
+	memory-region-names = "ospi1";
+	pinctrl-0 = <&ospi_port1_clk_pins_a
+		     &ospi_port1_io03_pins_a
+		     &ospi_port1_cs0_pins_a>;
+	pinctrl-1 = <&ospi_port1_clk_sleep_pins_a
+		     &ospi_port1_io03_sleep_pins_a
+		     &ospi_port1_cs0_sleep_pins_a>;
+	pinctrl-names = "default", "sleep";
+	status = "okay";
+
+	spi@0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		memory-region = <&mm_ospi1>;
+		status = "okay";
+
+		flash0: flash@0 {
+			compatible = "jedec,spi-nor";
+			reg = <0>;
+			spi-rx-bus-width = <4>;
+			spi-tx-bus-width = <4>;
+			spi-max-frequency = <50000000>;
+		};
+	};
+};
+
 &pcie_ep {
 	pinctrl-names = "default", "init";
 	pinctrl-0 = <&pcie_pins_a>;

-- 
2.43.0



^ permalink raw reply related

* [PATCH 2/5] ARM: dts: stm32: reorder cs_cti_trace node in stm32mp135f-dk.dts
From: Amelie Delaunay @ 2026-06-11  8:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
	Alexandre Torgue
  Cc: devicetree, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay
In-Reply-To: <20260611-node_reordering-v1-0-7e519f2cb456@foss.st.com>

In the ST board DTS files, the &label entries must be ordered
alphanumerically.
The nodes became misordered when Coresight support was added.

Move cs_cti_trace to the right place to avoid future misordering.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
 arch/arm/boot/dts/st/stm32mp135f-dk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index 6022e73f58af..bc3050a9bec5 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -190,11 +190,11 @@ &cryp {
 	status = "okay";
 };
 
-&cs_cti_trace {
+&cs_cti_cpu0 {
 	status = "okay";
 };
 
-&cs_cti_cpu0 {
+&cs_cti_trace {
 	status = "okay";
 };
 

-- 
2.43.0



^ permalink raw reply related

* [PATCH 0/5] ARM/arm64: dts: st: fix node ordering in ST board device trees
From: Amelie Delaunay @ 2026-06-11  8:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Maxime Coquelin,
	Alexandre Torgue
  Cc: devicetree, linux-stm32, linux-arm-kernel, linux-kernel,
	Amelie Delaunay

In the ST board DTS files, &label entries must be ordered
alphanumerically.
Over time, several nodes ended up out of order as a side effect of
adding new features or refactoring existing ones.
This series restores the correct alphanumeric ordering across
all ST board DTS files, with no functional change.

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
---
Amelie Delaunay (5):
      arm64: dts: st: reorder ommanager node in stm32mp257f-ev1.dts
      ARM: dts: stm32: reorder cs_cti_trace node in stm32mp135f-dk.dts
      ARM: dts: stm32: reorder cs_cti_trace node in stm32mp15xx-dkx.dtsi
      ARM: dts: stm32: reorder cs_cti_trace node in stm32mp157c-ev1.dts
      ARM: dts: stm32: reorder mdma1 node in stm32mp15*-scmi.dts

 arch/arm/boot/dts/st/stm32mp135f-dk.dts       |  4 +-
 arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts |  8 ++--
 arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts |  8 ++--
 arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts |  8 ++--
 arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts |  8 ++--
 arch/arm/boot/dts/st/stm32mp157c-ev1.dts      |  6 +--
 arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi     |  6 +--
 arch/arm64/boot/dts/st/stm32mp257f-ev1.dts    | 56 +++++++++++++--------------
 8 files changed, 52 insertions(+), 52 deletions(-)
---
base-commit: fba4a31a7f3b6b29b01c83180f83e7ed4c398738
change-id: 20260611-node_reordering-4b9b132b007f

Best regards,
-- 
Amelie Delaunay <amelie.delaunay@foss.st.com>



^ permalink raw reply

* Re: [PATCH v2 08/16] Revert "dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP"
From: Bartosz Golaszewski @ 2026-06-11  8:57 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Alan Stern, linux-acpi, driver-core, linux-pm, linux-usb,
	devicetree, linux-mediatek, linux-arm-kernel, linux-kernel,
	Manivannan Sadhasivam, Bartosz Golaszewski, Greg Kroah-Hartman,
	Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
	Rafael J. Wysocki, Danilo Krummrich, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno
In-Reply-To: <20260610084053.2059858-9-wenst@chromium.org>

On Wed, 10 Jun 2026 10:40:42 +0200, Chen-Yu Tsai <wenst@chromium.org> said:
> This reverts commit 454a1e3cd36c113341d7b71e8e691c6e47ab4a8a.
>
> mtk-xhci handles both USB 2.0 High Speed (HS) and USB 3.x SuperSpeed
> (SS) host connections. And there are USB 2.0 only mtk-xhci blocks.
> The SSUSB controller handles the device or gadget mode. Saying that
> SSUSB handles the HS portion is wrong.
>
> Fixes: 454a1e3cd36c ("dt-bindings: usb: mediatek,mtk-xhci: Add port for SuperSpeed EP")
> Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---

Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

Maybe put it in the front of the series?

Bart


^ permalink raw reply

* Re: [PATCH] crypto: atmel-ecc - drop dead code in atmel_ecdh_max_size
From: Herbert Xu @ 2026-06-11  8:54 UTC (permalink / raw)
  To: Thorsten Blum
  Cc: David S. Miller, Nicolas Ferre, Alexandre Belloni, Claudiu Beznea,
	linux-crypto, linux-arm-kernel, linux-kernel
In-Reply-To: <20260602222517.1071850-3-thorsten.blum@linux.dev>

On Wed, Jun 03, 2026 at 12:25:19AM +0200, Thorsten Blum wrote:
> atmel_ecdh_init_tfm() always allocates ctx->fallback, so it is never
> NULL in atmel_ecdh_max_size(). Remove the dead code and return
> crypto_kpp_maxsize() directly.
> 
> Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
> ---
>  drivers/crypto/atmel-ecc.c | 10 +---------
>  1 file changed, 1 insertion(+), 9 deletions(-)

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


^ permalink raw reply

* Re: [PATCH 19/37] drm/bridge: samsung-dsim: move drm_bridge_add() call to probe
From: Luca Ceresoli @ 2026-06-11  8:54 UTC (permalink / raw)
  To: Maxime Ripard, Luca Ceresoli
  Cc: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Simona Vetter,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
	Jonas Karlman, Jernej Skrabec, Inki Dae, Jagan Teki,
	Marek Szyprowski, Marek Vasut, Stefan Agner, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Hui Pu,
	Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel, imx,
	linux-arm-kernel
In-Reply-To: <20260608-mellow-weasel-of-politeness-a56172@houat>

On Mon Jun 8, 2026 at 1:58 PM CEST, Maxime Ripard wrote:
> On Tue, May 19, 2026 at 12:37:36PM +0200, Luca Ceresoli wrote:
>> This bridge driver calls drm_bridge_add() in the DSI host .attach callback
>> instead of in the probe function.
>>
>> This works for current use cases but is problematic for supporting hotplug
>> of DRM bridges. The problematic case is when this DSI host is always
>> present while its DSI device is hot-pluggable. In such case with the
>> current code the DRM card will not be populated until after the DSI device
>> attaches to the host, which could happen a very long time after booting, or
>> even not happen at all.
>>
>> The reason is that the previous pipeline component (the encoder in this
>> case) when probing cannot find the samsung-dsim bridge. What happens is:
>>
>>  [1 and 2 can happen in any order, same result]
>>  1) samsung-dsim probes (does not drm_bridge_add() itself)
>>  2) The lcdif starts probing multiple times, but
>>     lcdif_probe
>>     -> lcdif_load
>>        -> lcdif_attach_bridge
>>           -> devm_drm_of_get_bridge() returns -EPROBE_DEFER because
>>              the samsung-dsim is not in the global bridge_list
>>              (deferred probe pending: imx-lcdif: Cannot connect bridge)
>>
>> The samsung-dsim will not drm_bridge_add() itself until a DSI device will
>> try to mipi_dsi_attach() to the DSI Host, which can happen arbitratily late
>> on hot-pluggable hardware.
>>
>> As a preliminary step to supporting hotplug move drm_bridge_add() at probe
>> time, so that the samsung-dsim DSI host bridge is available during boot,
>> even without a connected DSI device. This results in:
>>
>>  1) samsung-dsim probes (and adds to drm_bridge_add() itself)
>>  2) The lcdif starts probing multiple times, but
>>     lcdif_probe
>>     -> lcdif_load
>>        -> lcdif_attach_bridge
>>           -> devm_drm_of_get_bridge() --> OK, returns samsung-dsim ptr
>>
>> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>
> We should probably amend
> https://www.kernel.org/doc/html/latest/gpu/drm-kms-helpers.html#special-care-with-mipi-dsi-bridges
>
> To mention this use case here

Right. I haven't updated the docs for this v1 because I was not sure the
overall approach would be acked. Now Dmitry acked it overall, and I kind of
infer you are not against, so I'll look into updating the docs in v2.

However I find that section of the docs a bit hard to read especially from
a newcomer perspective.

A better understanding on my side would help in doing the right change as
far as this patch is concerned, and as a bonus in improving the section
overall (that would probably be a separate series).

So I have a couple questions to start from:

 * Do I understand correctly that using the component framework is legacy,
   not recommended for new DRM development, and that converting existing
   code to stop using it is welcome?

 * The first bullet quotes "The upstream driver [...] isn’t a MIPI-DSI
   host". If the upstream driver of a MIPI DSI link isn't a MIPI DSI host,
   what else could it be? What are the use cases here?

 * If read literally, none of the 4 bullets after "Indeed, there’s multiple
   cases that needs to be considered" covers this driver (it does not use
   the component framework, it does not use DCS, and the upstream device is
   a DSI host). However the 3 bullets after "The ideal pattern to cover the
   last item" appear to cover what this driver does.  Do we need a fifth
   bullet for drivers like this one? Or...?

 * To me it looks like the "bridge" word in this section is always used to
   refer to the DSI device. Would it make sense to replace "bridge" ->
   "[DSI ]device" in this section? (especially as the DSI host is also a
   DRM bridge)

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


^ permalink raw reply

* Re: [PATCH] spi: xilinx: use FIFO occupancy register to determine buffer size
From: Michal Simek @ 2026-06-11  8:52 UTC (permalink / raw)
  To: lars.poeschel.linux, Mark Brown, linux-spi, linux-arm-kernel,
	linux-kernel
  Cc: Lars Pöschel, Mahapatra, Amit Kumar
In-Reply-To: <20260611071033.1937983-1-lars.poeschel.linux@edag.com>

+Amit,

On 6/11/26 09:10, lars.poeschel.linux@edag.com wrote:
> From: Lars Pöschel <lars.poeschel@edag.com>
> 
> The method the driver uses to determine the size of the FIFO has a
> problem. What it currently does is this:
> It stops the SPI hardware and writes to the TX FIFO register until TX
> FIFO FULL asserts in the status register. But the hardware does not only
> have the FIFO, it also seems to have a shift register. This can be seen,

I don't think you should guess here


> when writing a byte to the FIFO (while the SPI hardware is stopped,) the
> TX FIFO EMPTY is still empty. So, if we have a FIFO size of 16 for
> example, the current method returns a 17.




> This is a problem, at least when using the driver in irq mode. The same
> size determined for the TX FIFO is also assumed for the RX FIFO. When an
> SPI transaction wants to write the amount of the FIFO size or more
> bytes, the following happens, let's assume 16 bytes FIFO size:

s/let's/for example/


> The driver stops the SPI hardware and writes 17 bytes to the TX FIFO and
> starts the SPI hardware and goes sleep.
> The hardware then shifts out 17 bytes (FIFO + shift register) and
> simultaneously reads bytes into the RX FIFO, but it only has 16 places,
> so it looses one byte. Then TX FIFO empty asserts, wakes the driver
> again, which has a fast path and reads 16 bytes from the RX FIFO, but
> before reading the last 17th byte (which is lost) it does this:
> 
> 	sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);
> 	if (!(sr & XSPI_SR_RX_EMPTY_MASK)) {
> 		xilinx_spi_rx(xspi);
> 		rx_words--;
> 	}
> 
> It reads the status register and checks if the RX FIFO is not empty.
> But it is empty in our case. So this check spins in a while loop
> forever locking the driver.
> 
> The new method for determining the FIFO size is to read the SPITFOR (TX
> FIFO occupancy register, value = occupancy - 1) after filling the TX
> FIFO to obtain the true FIFO storage depth, which also equals the RX
> FIFO depth. In non-FIFO configurations (n_words == 1) the register does
> not exist; return 1 directly in that case.
> 

missing fix tag.

> Signed-off-by: Lars Pöschel <lars.poeschel@edag.com>
> ---
>   drivers/spi/spi-xilinx.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
> index 9f065d4e27d1..2d31e30fc4eb 100644
> --- a/drivers/spi/spi-xilinx.c
> +++ b/drivers/spi/spi-xilinx.c
> @@ -54,6 +54,7 @@
>   #define XSPI_RXD_OFFSET		0x6c	/* Data Receive Register */
>   
>   #define XSPI_SSR_OFFSET		0x70	/* 32-bit Slave Select Register */
> +#define XSPI_TFOR_OFFSET	0x74	/* Transmit FIFO Occupancy Register */
>   
>   /* Register definitions as per "OPB IPIF (v3.01c) Product Specification", DS414
>    * IPIF registers are 32 bit
> @@ -377,7 +378,9 @@ static int xilinx_spi_find_buffer_size(struct xilinx_spi *xspi)
>   		n_words++;
>   	} while (!(sr & XSPI_SR_TX_FULL_MASK));
>   
> -	return n_words;
> +	if (n_words == 1)
> +		return 1;
> +	return xspi->read_fn(xspi->regs + XSPI_TFOR_OFFSET) + 1;

Based on pg153
Exists only when FIFO Depth is set to 16 or 256

Based on ds570
This register does not exist if C_FIFO_EXIST = 0

It means this is not going to work with all HW configurations.

Pretty much you wanted to use this register to find out how big is the fifo
but I think in this case you should be just fixing logic around +-1 caused by 
n_words++ in a loop.

What about to change logic to be like this? It is clear and it is without any +1 
logic and no fifo is handled separately?

         while (1) { 
  

                 xspi->write_fn(0, xspi->regs + XSPI_TXD_OFFSET); 
  

                 sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); 
  

                 if (sr & XSPI_SR_TX_FULL_MASK) 
  

                         break; 
  

                 n_words++; 
  

         } 
  

  
  

         /* Handle NO FIFO case separately */ 
  

         if (!n_words) 
  

                 return 1; 
  

  
  

         return n_words;

Thanks,
Michal



^ permalink raw reply

* Re: [PATCH 0/2] gpio: fix sleeping-in-atomic in shared-proxy; restore meson non-sleeping
From: Marek Szyprowski @ 2026-06-11  8:26 UTC (permalink / raw)
  To: Viacheslav Bocharov, Linus Walleij, Bartosz Golaszewski
  Cc: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
	Robin Murphy, Diederik de Haas, linux-gpio, linux-arm-kernel,
	linux-amlogic, linux-kernel, linux-rockchip, Heiko Stuebner
In-Reply-To: <20260610153329.937833-1-v@baodeep.com>

Hi Viachesla,

On 10.06.2026 17:32, Viacheslav Bocharov wrote:
> gpio-shared-proxy chooses its descriptor lock (mutex vs spinlock) from
> the underlying chip's can_sleep, but under that lock it calls config and
> direction ops that reach sleeping pinctrl paths. On a controller with
> non-sleeping MMIO value ops the lock is a spinlock, so a sleeping call
> runs from atomic context:
>
>   BUG: sleeping function called from invalid context
>     ... pinctrl_gpio_set_config <- gpiochip_generic_config
>     <- gpio_shared_proxy_set_config (voting spinlock held)
>     <- ... <- mmc_pwrseq_simple_probe
>
> This was reported on Khadas VIM3 and worked around for Amlogic by
> commit 28f240683871 ("pinctrl: meson: mark the GPIO controller as
> sleeping"), which marked the whole meson controller sleeping. That
> workaround broke atomic value-path consumers: w1-gpio (1-Wire bitbang)
> no longer detects devices, because its IRQ-disabled read slot calls the
> non-cansleep gpiod_*_value() and now hits WARN_ON(can_sleep) per bit.
>
> Patch 1 fixes the proxy locking generically (always a sleeping mutex).
> Patch 2 then restores meson can_sleep=false, fixing 1-Wire.
>
> Patch 1 has a trade-off: a proxied GPIO becomes sleeping, so consumers
> gating on gpiod_cansleep() change behaviour. No current device needs
> atomic (non-cansleep) value access on a shared GPIO -- every report
> (Khadas VIM3, ODROID-M1, my test on JetHub D1+) is a shared reset line
> (eMMC/SDIO pwrseq or PCIe reset) driven through the cansleep accessors,
> which is what the proxy exists to vote on. An alternative that keeps
> atomic value access (split locking) is possible but adds a second lock
> and new race windows. I went with the simpler, verified approach and
> would appreciate guidance on whether the atomic value path must be
> preserved.
>
> The two are a unit: patch 2 must not be applied without patch 1,
> otherwise the original VIM3 splat returns on boards that share a meson
> GPIO -- please keep the order. I have not Cc'd stable; I will request
> stable backports separately once both patches have landed.
>
> Viacheslav Bocharov (2):
>   gpio: shared-proxy: always serialize with a sleeping mutex
>   pinctrl: meson: restore non-sleeping GPIO access

Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>

This probably also affects the similar changes in Rockchip GPIO driver done
by the following commits:
20cf2aed89ac ("gpio: rockchip: mark the GPIO controller as sleeping")
7ca497be0016 ("gpio: rockchip: Stop calling pinctrl for set_direction")

I've checked this patchset with these two reverted and no warning was reported.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



^ permalink raw reply

* Re: [PATCH v2] crypto: sun4i-ss - Remove insecure and unused rng_alg
From: Herbert Xu @ 2026-06-11  8:50 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-crypto, linux-sunxi, linux-arm-kernel, linux-kernel,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Corentin Labbe,
	stable, Tianchu Chen
In-Reply-To: <20260601160757.79645-1-ebiggers@kernel.org>

On Mon, Jun 01, 2026 at 04:07:57PM +0000, Eric Biggers wrote:
> Remove sun4i_ss_rng, as it is insecure and unused:
> 
> - It has multiple vulnerabilities.  sun4i_ss_prng_seed() is missing
>   locking and has a buffer overflow.  sun4i_ss_prng_generate() fails to
>   fill the entire buffer with cryptographic random bytes, because it
>   rounds the destination length down and also doesn't actually wait for
>   the hardware to be ready before pulling bytes from it.
> 
> - No user of this code is known.  It's usable only theoretically via the
>   "rng" algorithm type of AF_ALG.  But userspace actually just uses the
>   actual Linux RNG (/dev/random etc) instead.  And rng_algs don't
>   contribute entropy to the actual Linux RNG either.  (This may have
>   been confused with hwrng, which does contribute entropy.)
> 
> The sun4i_ss_prng_seed() buffer overflow was reported by Tianchu Chen
> and discovered by Atuin - Automated Vulnerability Discovery Engine
> 
> There's no point in fixing all these vulnerabilities individually when
> this is unused code, so let's just remove it.
> 
> Fixes: b8ae5c7387ad ("crypto: sun4i-ss - support the Security System PRNG")
> Cc: stable@vger.kernel.org
> Reported-by: Tianchu Chen <flynnnchen@tencent.com>
> Closes: https://lore.kernel.org/r/af749a8447bd7f0e9dd26ca6c87e9c6afecb09d9@linux.dev/
> Acked-by: Corentin LABBE <clabbe.montjoie@gmail.com>
> Signed-off-by: Eric Biggers <ebiggers@kernel.org>
> ---
> 
> This patch is targeting crypto/master
> 
> v2: rebased onto crypto/master, and added Acked-by and Reported-by
> 
>  arch/arm/configs/sunxi_defconfig              |  1 -
>  drivers/crypto/allwinner/Kconfig              |  8 ---
>  drivers/crypto/allwinner/sun4i-ss/Makefile    |  1 -
>  .../crypto/allwinner/sun4i-ss/sun4i-ss-core.c | 36 ----------
>  .../crypto/allwinner/sun4i-ss/sun4i-ss-prng.c | 69 -------------------
>  drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h  | 20 ------
>  6 files changed, 135 deletions(-)
>  delete mode 100644 drivers/crypto/allwinner/sun4i-ss/sun4i-ss-prng.c

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


^ permalink raw reply

* Re: [PATCH 0/4] Xilinx TRNG fix and simplification
From: Herbert Xu @ 2026-06-11  8:49 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-crypto, linux-kernel, Mounika Botcha, Harsh Jain,
	Olivia Mackall, Michal Simek, linux-arm-kernel
In-Reply-To: <20260531191738.55843-1-ebiggers@kernel.org>

On Sun, May 31, 2026 at 12:17:34PM -0700, Eric Biggers wrote:
> This series fixes and greatly simplifies the Xilinx TRNG driver by:
> 
> - Removing the gratuitous crypto_rng interface, leaving just hwrng which
>   is the one that actually matters.
> 
> - Replacing the really complicated AES based entropy extraction
>   algorithm with a much simpler one.
> 
> Note that this mirrors similar changes in other drivers.
> 
> Eric Biggers (4):
>   crypto: xilinx-trng - Remove crypto_rng interface
>   crypto: xilinx-trng - Fix return value of xtrng_hwrng_trng_read()
>   crypto: xilinx-trng - Replace crypto_drbg_ctr_df() with HMAC-SHA512
>   hwrng: xilinx - Move xilinx-rng into drivers/char/hw_random/
> 
>  MAINTAINERS                                   |   2 +-
>  arch/arm64/configs/defconfig                  |   2 +-
>  crypto/Kconfig                                |   5 -
>  crypto/Makefile                               |   2 -
>  crypto/df_sp80090a.c                          | 222 ------------------
>  drivers/char/hw_random/Kconfig                |  11 +
>  drivers/char/hw_random/Makefile               |   1 +
>  .../xilinx => char/hw_random}/xilinx-trng.c   | 134 ++---------
>  drivers/crypto/Kconfig                        |  13 -
>  drivers/crypto/xilinx/Makefile                |   1 -
>  include/crypto/df_sp80090a.h                  |  53 -----
>  11 files changed, 37 insertions(+), 409 deletions(-)
>  delete mode 100644 crypto/df_sp80090a.c
>  rename drivers/{crypto/xilinx => char/hw_random}/xilinx-trng.c (75%)
>  delete mode 100644 include/crypto/df_sp80090a.h
> 
> 
> base-commit: 5624ea54f3ba5c83d2e5503411a31a8be0278c1e
> prerequisite-patch-id: 07e982b663ac3f8312ca524f6b91b5b38661df5e
> prerequisite-patch-id: 72064361a8f36e015ab0b7e1fa4d364b40d90506
> prerequisite-patch-id: 8978b8e0db7f47935e5f6f0aff14a97f55d3073c
> prerequisite-patch-id: 6aa0e3e93a008279d71e535a3d0cf48643f55e19
> -- 
> 2.54.0

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


^ permalink raw reply

* Re: [PATCH 0/2] HiSilicon TRNG fix and simplification
From: Herbert Xu @ 2026-06-11  8:48 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-crypto, Olivia Mackall, Weili Qian, Wei Xu, Longfang Liu,
	linux-arm-kernel, linux-kernel
In-Reply-To: <20260530202624.20768-1-ebiggers@kernel.org>

On Sat, May 30, 2026 at 01:26:22PM -0700, Eric Biggers wrote:
> This series fixes and greatly simplifies the HiSilicon TRNG driver by
> removing the gratuitous crypto_rng interface, leaving just hwrng which
> is the one that actually matters.
> 
> Note that this mirrors similar changes in other drivers such as qcom-rng
> (https://lore.kernel.org/r/20260530020332.143058-1-ebiggers@kernel.org)
> 
> Eric Biggers (2):
>   crypto: hisi-trng - Remove crypto_rng interface
>   hwrng: hisi-trng - Move hisi-trng into drivers/char/hw_random/
> 
>  MAINTAINERS                            |   2 +-
>  arch/arm64/configs/defconfig           |   2 +-
>  drivers/char/hw_random/Kconfig         |  10 +
>  drivers/char/hw_random/Makefile        |   1 +
>  drivers/char/hw_random/hisi-trng-v2.c  |  98 +++++++
>  drivers/crypto/hisilicon/Kconfig       |   8 -
>  drivers/crypto/hisilicon/Makefile      |   1 -
>  drivers/crypto/hisilicon/trng/Makefile |   2 -
>  drivers/crypto/hisilicon/trng/trng.c   | 390 -------------------------
>  9 files changed, 111 insertions(+), 403 deletions(-)
>  create mode 100644 drivers/char/hw_random/hisi-trng-v2.c
>  delete mode 100644 drivers/crypto/hisilicon/trng/Makefile
>  delete mode 100644 drivers/crypto/hisilicon/trng/trng.c
> 
> 
> base-commit: 5624ea54f3ba5c83d2e5503411a31a8be0278c1e
> prerequisite-patch-id: 07e982b663ac3f8312ca524f6b91b5b38661df5e
> prerequisite-patch-id: 72064361a8f36e015ab0b7e1fa4d364b40d90506
> prerequisite-patch-id: 8978b8e0db7f47935e5f6f0aff14a97f55d3073c
> prerequisite-patch-id: 6aa0e3e93a008279d71e535a3d0cf48643f55e19
> -- 
> 2.54.0

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


^ permalink raw reply

* Re: [PATCH 0/2] clocksource/drivers/arm_arch_timer_mmio: Restore support for early init
From: Stephan Gerhold @ 2026-06-11  8:47 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Mark Rutland, Daniel Lezcano, Thomas Gleixner, Sudeep Holla,
	linux-arm-kernel, linux-kernel, linux-arm-msm, Jack Matthews
In-Reply-To: <87se6t8q3s.wl-maz@kernel.org>

On Thu, Jun 11, 2026 at 08:59:19AM +0100, Marc Zyngier wrote:
> On Wed, 10 Jun 2026 18:53:09 +0100,
> Stephan Gerhold <stephan.gerhold@linaro.org> wrote:
> > 
> > Jack reported a regression for some single-core Qualcomm platforms (e.g.
> > MDM9625, MDM9607) that no longer boot because no timers can be found during
> > early boot [1].
> 
> Again, this is *not* a regression. These machines were *never*
> supported upstream.
> 

Sorry, I'll reword this next time. MDM9607 does have all required
drivers and compatibles upstream already and is just missing the actual
DT so it does feel somewhat supported to me, but I'm fine treating this
as a feature extension without stable backporting etc.

> > These platforms rely on an obscure timer setup where the
> > global Arm MMIO timer (arm,armv7-timer-mem) is used as the only available
> > timer for the CPU. This setup used to work fine until commit 0f67b56d84b4
> > ("clocksource/drivers/arm_arch_timer_mmio: Switch over to standalone
> > driver") when the early timer initialization using TIMER_OF_DECLARE() was
> > removed when moving to the standalone MMIO driver.
> > 
> > There doesn't seem to be any other usable CPU timer on those platforms, so
> > this series restores the early timer support using TIMER_OF_DECLARE()
> > inside the new standalone arm_arch_timer_mmio driver. This is pretty ugly,
> > but I could not think of a better solution so far. I tried to keep the
> > ugliness for the two probe paths as limited as possible. :-)
> > 
> > If someone has a better idea how to solve this, I would be happy to try it.
> 
> I would suggest finding out what is the latest point in the init
> sequence where the timer can be probed without preventing boot.
> 

It doesn't get far without having any timer:

[    0.000000] timer_probe: no matching timers found
[    0.000000] entering initcall level: console
[    0.000000] calling  con_init+0x0/0x354 @ 0
[    0.000000] Console: colour dummy device 80x30
[    0.000000] initcall con_init+0x0/0x354 returned 0 after 0 usecs
[    0.000000] sched_clock: 32 bits at 300 Hz, resolution 3333333ns, wraps every 7158278824300949ns
[    0.000000] Calibrating delay loop... 
<board hangs>

If you look at start_kernel() in init/main.c it's basically time_init()
that would normally probe the TIMER_OF_DECLARE() timers and
calibrate_delay() that needs some timer to finish. There is also
random_init() that comes directly after time_init(), which already wants
to have access to timestamp counters. I don't see any other suitable
place to hook into. :-/

I also don't see any other timer we could use, at least for MDM9625.
It's a single-core Cortex-A5 and the downstream kernel defines only the
arm,armv7-timer-mem, which seems to be used for everything... (The
situation for MDM9607 is a bit different, but not any less messy,
unfortunately.)

Thanks,
Stephan


^ permalink raw reply

* Re: [PATCH v2 2/7] KVM: arm64: Support FFA_NOTIFICATION_BITMAP_DESTROY in host handler
From: Sebastian Ene @ 2026-06-11  8:47 UTC (permalink / raw)
  To: Vincent Donnefort
  Cc: catalin.marinas, maz, oupton, will, joey.gouly, korneld, kvmarm,
	linux-arm-kernel, linux-kernel, android-kvm, mrigendra.chaubey,
	perlarsen, suzuki.poulose, yuzenghui
In-Reply-To: <aikmBBHEUfolXrHC@google.com>

On Wed, Jun 10, 2026 at 09:53:24AM +0100, Vincent Donnefort wrote:
> On Mon, Jun 08, 2026 at 04:55:44PM +0000, Sebastian Ene wrote:
> > Allow FF-A notification bitmap destruction messages to be forwarded to
> > Trustzone from the host.
> > 
> > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> > ---
> >  arch/arm64/kvm/hyp/nvhe/ffa.c | 24 +++++++++++++++++++++++-
> >  1 file changed, 23 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > index c20d45191085..91e89d889c44 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > @@ -688,7 +688,6 @@ static bool ffa_call_supported(u64 func_id)
> >  	case FFA_MEM_DONATE:
> >  	case FFA_MEM_RETRIEVE_REQ:
> >         /* Optional notification interfaces added in FF-A 1.1 */
> > -	case FFA_NOTIFICATION_BITMAP_DESTROY:
> >  	case FFA_NOTIFICATION_BIND:
> >  	case FFA_NOTIFICATION_UNBIND:
> >  	case FFA_NOTIFICATION_SET:
> > @@ -893,6 +892,26 @@ static void do_ffa_notif_bitmap_create(struct arm_smccc_1_2_regs *res,
> >  	arm_smccc_1_2_smc(args, res);
> >  }
> >  
> > +static void do_ffa_notif_bitmap_destroy(struct arm_smccc_1_2_regs *res,
> > +					struct kvm_cpu_context *ctxt)
> > +{
> > +	DECLARE_REG(u32, vmid, ctxt, 1);
> > +	struct arm_smccc_1_2_regs *args;
> > +
> > +	if (ffa_check_unused_args_sbz(ctxt, 2)) {
> > +		ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
> > +		return;
> > +	}
> > +
> > +	if (vmid != HOST_FFA_ID) {
> > +		ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
> > +		return;
> > +	}
> > +
> > +	args = (void *)&ctxt->regs.regs[0];
> > +	arm_smccc_1_2_smc(args, res);
> > +}

Hello Vincent,

> 
> Sounds exactly like do_ffa_notif_bitmap_create. Could we use a single one
> "do_ffa_notif_bitmap" ? 
> 

Yes, I guess we can have only one method since the only difference
between them is in the number of unused args.

> > +
> >  bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
> >  {
> >  	struct arm_smccc_1_2_regs res;
> > @@ -954,6 +973,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
> >  	case FFA_NOTIFICATION_BITMAP_CREATE:
> >  		do_ffa_notif_bitmap_create(&res, host_ctxt);
> >  		goto out_handled;
> > +	case FFA_NOTIFICATION_BITMAP_DESTROY:
> > +		do_ffa_notif_bitmap_destroy(&res, host_ctxt);
> > +		goto out_handled;
> >  	}
> >  
> >  	if (ffa_call_supported(func_id))
> > -- 
> > 2.54.0.1064.gd145956f57-goog
> > 

Thanks,
Sebastian


^ permalink raw reply

* Re: (subset) [PATCH v4 1/2] dt-bindings: mfd: st,stmpe: Add missing properties for PWM subnode
From: Lee Jones @ 2026-06-11  8:46 UTC (permalink / raw)
  To: lee, ukleinek, robh, krzk+dt, conor+dt, mcoquelin.stm32,
	alexandre.torgue, linusw, Manish Baing
  Cc: linux-pwm, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Conor Dooley
In-Reply-To: <20260523173251.72540-2-manishbaing2789@gmail.com>

On Sat, 23 May 2026 17:32:50 +0000, Manish Baing wrote:
> The st,stmpe-pwm binding is already covered by the MFD schema in
> Documentation/devicetree/bindings/mfd/st,stmpe.yaml. However, the
> PWM subnode was missing a 'required' properties block. This allowed
> Device Tree nodes to pass validation even if the 'compatible'
> string was omitted. This omission could lead to probe failures
> at runtime.
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: mfd: st,stmpe: Add missing properties for PWM subnode
      commit: b07f7904e0523170856876e4412be852377d492a

--
Lee Jones [李琼斯]



^ permalink raw reply

* [PATCH v2 2/2] iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free on teardown
From: Shameer Kolothum @ 2026-06-11  8:42 UTC (permalink / raw)
  To: iommu, linux-kernel, linux-arm-kernel
  Cc: nicolinc, jgg, joro, will, robin.murphy, nathanc, mochs,
	skolothumtho
In-Reply-To: <20260611084205.686559-1-skolothumtho@nvidia.com>

arm_smmu_impl_remove() is registered as a devres action in
arm_smmu_impl_probe(), before arm_smmu_init_queues() allocates
smmu->cmdq.q.base. On a devres unwind, whether a failed probe or an
unbind, the queue is freed first and arm_smmu_impl_remove() then runs
tegra241_cmdqv_remove_vintf(), whose VINTF deinit issues a CMD_SYNC on
the freed memory.

Observed during testing with a QEMU hack that makes the VCMDQ fail to
enable, so the impl reset fails and probe aborts into the devres unwind:

 platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: failed to enable, STATUS=0x00000000
 platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: GERRORN=0x0, GERROR=0x4, CONS=0x0
 platform NVDA200C:00: tegra241_cmdqv: VINTF0: VCMDQ0/LVCMDQ0: uncleared error detected, resetting
 arm-smmu-v3 arm-smmu-v3.0.auto: failed to reset impl
 arm-smmu-v3 arm-smmu-v3.0.auto: probe with driver arm-smmu-v3 failed with error -110
 Unable to handle kernel paging request at virtual address ffff8000891e0098
 ...
 Internal error: Oops: 0000000096000047 [#1] SMP
 ...
 Call trace:
  arm_smmu_cmdq_issue_cmdlist+0x320/0x6fc (P)
  tegra241_vcmdq_hw_deinit+0x98/0x168
  tegra241_vintf_hw_deinit+0x5c/0x1b0
  tegra241_cmdqv_remove_vintf+0x34/0xec
  tegra241_cmdqv_remove+0x40/0x9c
  arm_smmu_impl_remove+0x20/0x30
  devm_action_release+0x14/0x20
  devres_release_all+0xa8/0x110
  device_unbind_cleanup+0x18/0x84
  really_probe+0x1f0/0x29c

Drop the VINTF deinit from tegra241_cmdqv_remove_vintf() so the unwind no
longer touches the freed queue. Quiesce the VINTFs earlier instead. Add a
device_disable() impl op and run it from arm_smmu_disable_action() while
the CMDQ is still up. That handles a live unbind. A failed reset is already
handled because tegra241_vintf_hw_init() deinits the VINTF on its own error
path. tegra241_cmdqv_remove_vintf() is also used by the iommufd viommu
destroy path, so quiesce there too.

Fixes: 4dc0d12474f9 ("iommu/tegra241-cmdqv: Add user-space use support")
Cc: stable@vger.kernel.org
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h    |  1 +
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c    |  6 +++++-
 drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c | 15 +++++++++++++--
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index ef42df4753ec..690055aa63c7 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -804,6 +804,7 @@ struct arm_smmu_strtab_cfg {
 
 struct arm_smmu_impl_ops {
 	int (*device_reset)(struct arm_smmu_device *smmu);
+	void (*device_disable)(struct arm_smmu_device *smmu);
 	void (*device_remove)(struct arm_smmu_device *smmu);
 	int (*init_structures)(struct arm_smmu_device *smmu);
 	struct arm_smmu_cmdq *(*get_secondary_cmdq)(
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 00261e77e7bc..3d531af7e16c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4800,7 +4800,11 @@ static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
 
 static void arm_smmu_disable_action(void *data)
 {
-	arm_smmu_device_disable(data);
+	struct arm_smmu_device *smmu = data;
+
+	if (smmu->impl_ops && smmu->impl_ops->device_disable)
+		smmu->impl_ops->device_disable(smmu);
+	arm_smmu_device_disable(smmu);
 }
 
 static void arm_smmu_write_strtab(struct arm_smmu_device *smmu)
diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
index 83f6e9f6c51d..c7af7658a4ea 100644
--- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
+++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c
@@ -761,8 +761,6 @@ static void tegra241_cmdqv_remove_vintf(struct tegra241_cmdqv *cmdqv, u16 idx)
 	struct tegra241_vintf *vintf = cmdqv->vintfs[idx];
 	u16 lidx;
 
-	tegra241_vintf_hw_deinit(vintf);
-
 	/* Remove LVCMDQ resources */
 	for (lidx = 0; lidx < vintf->cmdqv->num_lvcmdqs_per_vintf; lidx++)
 		if (vintf->lvcmdqs[lidx])
@@ -779,6 +777,17 @@ static void tegra241_cmdqv_remove_vintf(struct tegra241_cmdqv *cmdqv, u16 idx)
 	}
 }
 
+static void tegra241_cmdqv_hw_disable(struct arm_smmu_device *smmu)
+{
+	struct tegra241_cmdqv *cmdqv =
+		container_of(smmu, struct tegra241_cmdqv, smmu);
+	u16 idx;
+
+	for (idx = 0; idx < cmdqv->num_vintfs; idx++)
+		if (cmdqv->vintfs[idx])
+			tegra241_vintf_hw_deinit(cmdqv->vintfs[idx]);
+}
+
 static void tegra241_cmdqv_remove(struct arm_smmu_device *smmu)
 {
 	struct tegra241_cmdqv *cmdqv =
@@ -844,6 +853,7 @@ static struct arm_smmu_impl_ops tegra241_cmdqv_impl_ops = {
 	/* For in-kernel use */
 	.get_secondary_cmdq = tegra241_cmdqv_get_cmdq,
 	.device_reset = tegra241_cmdqv_hw_reset,
+	.device_disable = tegra241_cmdqv_hw_disable,
 	.device_remove = tegra241_cmdqv_remove,
 	/* For user-space use */
 	.hw_info = tegra241_cmdqv_hw_info,
@@ -1152,6 +1162,7 @@ static void tegra241_cmdqv_destroy_vintf_user(struct iommufd_viommu *viommu)
 	if (vintf->mmap_offset)
 		iommufd_viommu_destroy_mmap(&vintf->vsmmu.core,
 					    vintf->mmap_offset);
+	tegra241_vintf_hw_deinit(vintf);
 	tegra241_cmdqv_remove_vintf(vintf->cmdqv, vintf->idx);
 }
 
-- 
2.43.0



^ permalink raw reply related

* [PATCH v2 1/2] iommu/arm-smmu-v3: Manage teardown with devm
From: Shameer Kolothum @ 2026-06-11  8:42 UTC (permalink / raw)
  To: iommu, linux-kernel, linux-arm-kernel
  Cc: nicolinc, jgg, joro, will, robin.murphy, nathanc, mochs,
	skolothumtho
In-Reply-To: <20260611084205.686559-1-skolothumtho@nvidia.com>

arm_smmu_device_remove() manually frees the IOPF queue, destroys the
vmid_map and disables the device, while the IRQs and queues are devm
managed. devm unwinds only after remove() returns, so the cleanup runs
in the wrong order. The IOPF queue is freed before the event-queue IRQ
whose handler uses it.

Manage all of it with devm so the unwind order is correct. Free the IOPF
queue and vmid_map via devm actions, and disable the device from one
registered after arm_smmu_device_reset().

This is also a prerequisite for fixing a Tegra241 CMDQV CMD_SYNC
use-after-free in the subsequent patch.

Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 50 ++++++++++++++-------
 1 file changed, 34 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index e8d7dbe495f0..00261e77e7bc 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4464,6 +4464,16 @@ int arm_smmu_cmdq_init(struct arm_smmu_device *smmu,
 	return 0;
 }
 
+static void arm_smmu_free_iopf_action(void *data)
+{
+	iopf_queue_free(data);
+}
+
+static void arm_smmu_destroy_vmid_map(void *data)
+{
+	ida_destroy(data);
+}
+
 static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
 {
 	int ret;
@@ -4491,6 +4501,11 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
 		smmu->evtq.iopf = iopf_queue_alloc(dev_name(smmu->dev));
 		if (!smmu->evtq.iopf)
 			return -ENOMEM;
+		ret = devm_add_action_or_reset(smmu->dev,
+					       arm_smmu_free_iopf_action,
+					       smmu->evtq.iopf);
+		if (ret)
+			return ret;
 	}
 
 	/* priq */
@@ -4569,7 +4584,8 @@ static int arm_smmu_init_strtab(struct arm_smmu_device *smmu)
 
 	ida_init(&smmu->vmid_map);
 
-	return 0;
+	return devm_add_action_or_reset(smmu->dev, arm_smmu_destroy_vmid_map,
+					&smmu->vmid_map);
 }
 
 static int arm_smmu_init_structures(struct arm_smmu_device *smmu)
@@ -4782,6 +4798,11 @@ static int arm_smmu_device_disable(struct arm_smmu_device *smmu)
 	return ret;
 }
 
+static void arm_smmu_disable_action(void *data)
+{
+	arm_smmu_device_disable(data);
+}
+
 static void arm_smmu_write_strtab(struct arm_smmu_device *smmu)
 {
 	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
@@ -5540,7 +5561,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Initialise in-memory data structures */
 	ret = arm_smmu_init_structures(smmu);
 	if (ret)
-		goto err_free_iopf;
+		return ret;
 
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
@@ -5550,30 +5571,30 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 
 	/* Reset the device */
 	ret = arm_smmu_device_reset(smmu);
+	if (ret) {
+		arm_smmu_device_disable(smmu);
+		return ret;
+	}
+
+	/* Register last so it unwinds first, while the CMDQ is still up. */
+	ret = devm_add_action_or_reset(smmu->dev, arm_smmu_disable_action, smmu);
 	if (ret)
-		goto err_disable;
+		return ret;
 
 	/* And we're up. Go go go! */
 	ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
 				     "smmu3.%pa", &ioaddr);
 	if (ret)
-		goto err_disable;
+		return ret;
 
 	ret = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
 	if (ret) {
 		dev_err(dev, "Failed to register iommu\n");
-		goto err_free_sysfs;
+		iommu_device_sysfs_remove(&smmu->iommu);
+		return ret;
 	}
 
 	return 0;
-
-err_free_sysfs:
-	iommu_device_sysfs_remove(&smmu->iommu);
-err_disable:
-	arm_smmu_device_disable(smmu);
-err_free_iopf:
-	iopf_queue_free(smmu->evtq.iopf);
-	return ret;
 }
 
 static void arm_smmu_device_remove(struct platform_device *pdev)
@@ -5582,9 +5603,6 @@ static void arm_smmu_device_remove(struct platform_device *pdev)
 
 	iommu_device_unregister(&smmu->iommu);
 	iommu_device_sysfs_remove(&smmu->iommu);
-	arm_smmu_device_disable(smmu);
-	iopf_queue_free(smmu->evtq.iopf);
-	ida_destroy(&smmu->vmid_map);
 }
 
 static void arm_smmu_device_shutdown(struct platform_device *pdev)
-- 
2.43.0



^ permalink raw reply related


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