* [PATCH v4 2/3] i2c: ma35d1: Add Nuvoton MA35D1 I2C driver support
From: Zi-Yu Chen @ 2026-06-10 3:02 UTC (permalink / raw)
To: Andi Shyti
Cc: Jacky Huang, Shan-Chun Hung, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-i2c, devicetree,
linux-arm-kernel, linux-kernel, Zi-Yu Chen
In-Reply-To: <20260610030208.2020275-1-zychennvt@gmail.com>
Add I2C support for Nuvoton MA35D1 SoC.
The controller supports standard, fast and fast-plus modes,
and provides controller/target functionality.
Signed-off-by: Zi-Yu Chen <zychennvt@gmail.com>
---
drivers/i2c/busses/Kconfig | 13 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-ma35d1.c | 778 ++++++++++++++++++++++++++++++++
3 files changed, 792 insertions(+)
create mode 100644 drivers/i2c/busses/i2c-ma35d1.c
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 8c935f867a37..816c55814ed4 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1590,4 +1590,17 @@ config I2C_VIRTIO
This driver can also be built as a module. If so, the module
will be called i2c-virtio.
+config I2C_MA35D1
+ tristate "Nuvoton MA35D1 I2C driver"
+ depends on ARCH_MA35 || COMPILE_TEST
+ select I2C_SLAVE
+ help
+ If you say yes to this option, support will be included for the
+ I2C controller in the Nuvoton MA35D1 SoC. This driver
+ supports the standard I2C bus protocols, including master and
+ slave modes.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-ma35d1.
+
endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 547123ab351f..264f6f3f608d 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -130,6 +130,7 @@ obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o
obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
obj-$(CONFIG_I2C_GXP) += i2c-gxp.o
+obj-$(CONFIG_I2C_MA35D1) += i2c-ma35d1.o
# External I2C/SMBus adapter drivers
obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-ma35d1.c b/drivers/i2c/busses/i2c-ma35d1.c
new file mode 100644
index 000000000000..7b6b20c0996d
--- /dev/null
+++ b/drivers/i2c/busses/i2c-ma35d1.c
@@ -0,0 +1,778 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Nuvoton technology corporation.
+ *
+ * Author: Zi-Yu Chen <zychennvt@gmail.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+/* MA35D1 I2C registers offset */
+#define MA35_CTL0 0x00
+#define MA35_ADDR0 0x04
+#define MA35_DAT 0x08
+#define MA35_STATUS0 0x0c
+#define MA35_CLKDIV 0x10
+#define MA35_TOCTL 0x14
+#define MA35_ADDR1 0x18
+#define MA35_ADDR2 0x1c
+#define MA35_ADDR3 0x20
+#define MA35_ADDRMSK0 0x24
+#define MA35_ADDRMSK1 0x28
+#define MA35_ADDRMSK2 0x2c
+#define MA35_ADDRMSK3 0x30
+#define MA35_WKCTL 0x3c
+#define MA35_WKSTS 0x40
+#define MA35_CTL1 0x44
+#define MA35_STATUS1 0x48
+#define MA35_TMCTL 0x4c
+#define MA35_BUSCTL 0x50
+#define MA35_BUSTCTL 0x54
+#define MA35_BUSSTS 0x58
+#define MA35_PKTSIZE 0x5c
+#define MA35_PKTCRC 0x60
+#define MA35_BUSTOUT 0x64
+#define MA35_CLKTOUT 0x68
+#define MA35_AUTOCNT 0x78
+
+/* MA35D1 I2C Status */
+/* Controller */
+#define MA35_M_START 0x08 /* Start */
+#define MA35_M_REPEAT_START 0x10 /* Controller Repeat Start */
+#define MA35_M_TRAN_ADDR_ACK 0x18 /* Controller Transmit Address ACK */
+#define MA35_M_TRAN_ADDR_NACK 0x20 /* Controller Transmit Address NACK */
+#define MA35_M_TRAN_DATA_ACK 0x28 /* Controller Transmit Data ACK */
+#define MA35_M_TRAN_DATA_NACK 0x30 /* Controller Transmit Data NACK */
+#define MA35_M_ARB_LOST 0x38 /* Controller Arbitration Lost */
+#define MA35_M_RECE_ADDR_ACK 0x40 /* Controller Receive Address ACK */
+#define MA35_M_RECE_ADDR_NACK 0x48 /* Controller Receive Address NACK */
+#define MA35_M_RECE_DATA_ACK 0x50 /* Controller Receive Data ACK */
+#define MA35_M_RECE_DATA_NACK 0x58 /* Controller Receive Data NACK */
+#define MA35_BUS_ERROR 0x00 /* Bus error */
+
+/* Target */
+#define MA35_S_REPEAT_START_STOP 0xa0 /* Target Transmit Repeat Start or Stop */
+#define MA35_S_TRAN_ADDR_ACK 0xa8 /* Target Transmit Address ACK */
+#define MA35_S_TRAN_DATA_ACK 0xb8 /* Target Transmit Data ACK */
+#define MA35_S_TRAN_DATA_NACK 0xc0 /* Target Transmit Data NACK */
+#define MA35_S_TRAN_LAST_DATA_ACK 0xc8 /* Target Transmit Last Data ACK */
+#define MA35_S_RECE_ADDR_ACK 0x60 /* Target Receive Address ACK */
+#define MA35_S_RECE_ARB_LOST 0x68 /* Target Receive Arbitration Lost */
+#define MA35_S_RECE_DATA_ACK 0x80 /* Target Receive Data ACK */
+#define MA35_S_RECE_DATA_NACK 0x88 /* Target Receive Data NACK */
+
+/* GC Mode */
+#define MA35_GC_ADDR_ACK 0x70 /* GC mode Address ACK */
+#define MA35_GC_ARB_LOST 0x78 /* GC mode Arbitration Lost */
+#define MA35_GC_DATA_ACK 0x90 /* GC mode Data ACK */
+#define MA35_GC_DATA_NACK 0x98 /* GC mode Data NACK */
+
+/* Other */
+#define MA35_ADDR_TRAN_ARB_LOST 0xb0 /* Address Transmit Arbitration Lost */
+#define MA35_BUS_RELEASED 0xf8 /* Bus Released */
+
+/* I2C_CTL constant definitions. */
+#define MA35_CTL_AA BIT(2)
+#define MA35_CTL_SI BIT(3)
+#define MA35_CTL_STO BIT(4)
+#define MA35_CTL_STA BIT(5)
+#define MA35_CTL_I2CEN BIT(6)
+#define MA35_CTL_INTEN BIT(7)
+#define MA35_CTL_SI_AA (MA35_CTL_SI | MA35_CTL_AA)
+#define MA35_CTL_STO_SI (MA35_CTL_STO | MA35_CTL_SI)
+#define MA35_CTL_STA_SI (MA35_CTL_STA | MA35_CTL_SI)
+#define MA35_CTL_STA_SI_AA (MA35_CTL_STA | MA35_CTL_SI | MA35_CTL_AA)
+#define MA35_CTL_STO_SI_AA (MA35_CTL_STO | MA35_CTL_SI | MA35_CTL_AA)
+
+/* Constants */
+#define MA35_CLKDIV_MSK GENMASK(15, 0)
+#define MA35_I2C_ADDR_MASK (0x7f << 1)
+#define I2C_PM_TIMEOUT_MS 5000
+#define STOP_TIMEOUT_MS 50
+#define MA35_I2C_GC_EN 1
+#define MA35_I2C_GC_DIS 0
+
+struct ma35d1_i2c {
+ wait_queue_head_t wait;
+ struct i2c_msg *msg;
+ unsigned int msg_num;
+ unsigned int msg_idx;
+ unsigned int msg_ptr;
+ int err;
+ int irq;
+ void __iomem *regs;
+ struct clk *clk;
+ struct device *dev;
+ struct i2c_adapter adap;
+ struct i2c_client *target;
+ struct reset_control *rst;
+};
+
+static inline bool ma35d1_is_controller_status(unsigned int status)
+{
+ return status >= MA35_M_START && status <= MA35_M_RECE_DATA_NACK;
+}
+
+/*
+ * ma35d1_i2c_write_CTL - Update the I2C control register
+ * @i2c: Pointer to the ma35d1 i2c instance
+ * @ctl: Control bits to set (e.g., MA35_CTL_STA, SI, AA)
+ *
+ * This helper reads CTL0, clears the sticky state-change bits (STA, STO, SI, AA),
+ * and then applies the new control bits provided by @ctl.
+ */
+static void ma35d1_i2c_write_CTL(struct ma35d1_i2c *i2c, unsigned int ctl)
+{
+ unsigned int val;
+
+ val = readl(i2c->regs + MA35_CTL0);
+ val &= ~(MA35_CTL_STA_SI_AA | MA35_CTL_STO);
+ val |= ctl;
+ writel(val, i2c->regs + MA35_CTL0);
+}
+
+static void ma35d1_i2c_set_addr(struct ma35d1_i2c *i2c)
+{
+ unsigned int rw = i2c->msg->flags & I2C_M_RD;
+
+ writel(((i2c->msg->addr & 0x7f) << 1) | rw, i2c->regs + MA35_DAT);
+}
+
+static void ma35d1_i2c_controller_complete(struct ma35d1_i2c *i2c)
+{
+ dev_dbg(i2c->dev, "controller_complete\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg = NULL;
+ i2c->msg_idx++;
+ i2c->msg_num = 0;
+
+ wake_up(&i2c->wait);
+}
+
+static void ma35d1_i2c_disable_irq(struct ma35d1_i2c *i2c)
+{
+ unsigned long tmp;
+
+ tmp = readl(i2c->regs + MA35_CTL0);
+ writel(tmp & ~MA35_CTL_INTEN, i2c->regs + MA35_CTL0);
+}
+
+static void ma35d1_i2c_enable_irq(struct ma35d1_i2c *i2c)
+{
+ unsigned long tmp;
+
+ tmp = readl(i2c->regs + MA35_CTL0);
+ writel(tmp | MA35_CTL_INTEN, i2c->regs + MA35_CTL0);
+}
+
+static void ma35d1_i2c_reset(struct ma35d1_i2c *i2c)
+{
+ unsigned int clkdiv, slvaddr;
+
+ clkdiv = readl(i2c->regs + MA35_CLKDIV);
+ slvaddr = readl(i2c->regs + MA35_ADDR0);
+
+ reset_control_assert(i2c->rst);
+ reset_control_deassert(i2c->rst);
+
+ writel(clkdiv, (i2c->regs + MA35_CLKDIV));
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_I2CEN);
+
+ if (i2c->target)
+ writel(slvaddr, i2c->regs + MA35_ADDR0);
+}
+
+static void ma35d1_i2c_stop(struct ma35d1_i2c *i2c, int ret)
+{
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_STO_SI);
+
+ if (ret)
+ i2c->err = ret;
+
+ ma35d1_i2c_controller_complete(i2c);
+}
+
+/* Check if this is the last message in the set */
+static inline bool is_last_msg(struct ma35d1_i2c *i2c)
+{
+ return i2c->msg_idx >= (i2c->msg_num - 1);
+}
+
+/* Check if this is the last byte in the current message */
+static inline bool is_last_byte(struct ma35d1_i2c *i2c)
+{
+ return i2c->msg_ptr == i2c->msg->len - 1;
+}
+
+/* Check if reached the end of the current message */
+static inline bool is_msgend(struct ma35d1_i2c *i2c)
+{
+ return i2c->msg_ptr >= i2c->msg->len;
+}
+
+/*
+ * i2c_ma35d1_irq_target_trx - I2C Target state machine handler
+ * @i2c: ma35d1 i2c instance
+ * @i2c_status: hardware status code from MA35_STATUS0
+ */
+static void i2c_ma35d1_irq_target_trx(struct ma35d1_i2c *i2c,
+ unsigned long i2c_status)
+{
+ unsigned char byte;
+
+ switch (i2c_status) {
+ case MA35_S_RECE_ADDR_ACK:
+ /* Own SLA+W has been receive; ACK has been return */
+ i2c_slave_event(i2c->target, I2C_SLAVE_WRITE_REQUESTED, &byte);
+ break;
+ case MA35_S_TRAN_DATA_NACK:
+ /* Data byte or last data in I2CDAT has been transmitted.
+ * Not ACK has been received
+ */
+ case MA35_S_RECE_DATA_NACK:
+ /* Previously addressed with own SLA address;
+ * NOT ACK has been returned
+ */
+ break;
+
+ case MA35_S_RECE_DATA_ACK:
+ /* Previously address with own SLA address Data has been received;
+ * ACK has been returned
+ */
+ byte = readb(i2c->regs + MA35_DAT);
+ i2c_slave_event(i2c->target, I2C_SLAVE_WRITE_RECEIVED, &byte);
+ break;
+
+ case MA35_S_TRAN_ADDR_ACK:
+ /* Own SLA+R has been receive; ACK has been return */
+ i2c_slave_event(i2c->target, I2C_SLAVE_READ_REQUESTED, &byte);
+
+ writel(byte, i2c->regs + MA35_DAT);
+ break;
+
+ case MA35_S_TRAN_DATA_ACK:
+ i2c_slave_event(i2c->target, I2C_SLAVE_READ_PROCESSED, &byte);
+ writel(byte, i2c->regs + MA35_DAT);
+ break;
+
+ case MA35_S_REPEAT_START_STOP:
+ /* A STOP or repeated START has been received
+ * while still addressed as Target/Receiver
+ */
+ i2c_slave_event(i2c->target, I2C_SLAVE_STOP, &byte);
+ break;
+
+ default:
+ dev_err(i2c->dev, "Status 0x%02lx is NOT processed\n",
+ i2c_status);
+ break;
+ }
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI_AA);
+}
+
+/*
+ * i2c_ma35d1_irq_controller_trx - I2C Controller state machine handler
+ * @i2c: ma35d1 i2c instance
+ * @i2c_status: hardware status code from MA35_STATUS0
+ */
+static void i2c_ma35d1_irq_controller_trx(struct ma35d1_i2c *i2c,
+ unsigned long i2c_status)
+{
+ unsigned char byte;
+
+ switch (i2c_status) {
+ case MA35_M_START:
+ case MA35_M_REPEAT_START:
+ ma35d1_i2c_set_addr(i2c);
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI);
+ break;
+
+ case MA35_M_TRAN_ADDR_ACK:
+ case MA35_M_TRAN_DATA_ACK:
+ /* SLA+W has been transmitted and ACK has been received */
+ if (i2c_status == MA35_M_TRAN_ADDR_ACK) {
+ if (is_last_msg(i2c) && i2c->msg->len == 0) {
+ ma35d1_i2c_stop(i2c, 0);
+ return;
+ }
+ }
+
+ if (!is_msgend(i2c)) {
+ byte = i2c->msg->buf[i2c->msg_ptr++];
+ writel(byte, i2c->regs + MA35_DAT);
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI);
+ } else if (!is_last_msg(i2c)) {
+ dev_dbg(i2c->dev, "WRITE: Next Message\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx++;
+ i2c->msg++;
+
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_STA | MA35_CTL_SI);
+ } else {
+ ma35d1_i2c_stop(i2c, 0);
+ }
+ break;
+
+ case MA35_M_TRAN_DATA_NACK:
+ ma35d1_i2c_stop(i2c, -EIO);
+ break;
+
+ case MA35_M_TRAN_ADDR_NACK:
+ case MA35_M_RECE_ADDR_NACK:
+ /* Controller Transmit Address NACK */
+ /* 0x20: SLA+W has been transmitted and NACK has been received */
+ /* 0x48: SLA+R has been transmitted and NACK has been received */
+ if (i2c->msg->flags & I2C_M_IGNORE_NAK) {
+ ma35d1_i2c_stop(i2c, 0);
+ } else {
+ dev_dbg(i2c->dev, "\n i2c: ack was not received\n");
+ ma35d1_i2c_stop(i2c, -ENXIO);
+ }
+ break;
+
+ case MA35_M_RECE_ADDR_ACK:
+ if (is_msgend(i2c)) {
+ if (is_last_msg(i2c)) {
+ ma35d1_i2c_stop(i2c, 0);
+ } else {
+ dev_dbg(i2c->dev, "READ: Next Transfer\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx++;
+ i2c->msg++;
+
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_STA_SI);
+ }
+ } else if (i2c->msg->len == 1) {
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI);
+ } else {
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI_AA);
+ }
+ break;
+
+ case MA35_M_RECE_DATA_ACK:
+ case MA35_M_RECE_DATA_NACK:
+ /* DATA has been transmitted and ACK has been received */
+ byte = readb(i2c->regs + MA35_DAT);
+ i2c->msg->buf[i2c->msg_ptr++] = byte;
+
+ if (is_last_byte(i2c)) {
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI);
+ } else if (is_msgend(i2c)) {
+ if (is_last_msg(i2c)) {
+ dev_dbg(i2c->dev, "READ: Send Stop\n");
+
+ ma35d1_i2c_stop(i2c, 0);
+ } else {
+ dev_dbg(i2c->dev, "READ: Next Transfer\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx++;
+ i2c->msg++;
+
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_STA_SI);
+ }
+ } else {
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI_AA);
+ }
+ break;
+
+ default:
+ dev_err(i2c->dev, "Status 0x%02lx is NOT processed\n",
+ i2c_status);
+ ma35d1_i2c_stop(i2c, -EIO);
+ break;
+ }
+}
+
+static irqreturn_t ma35d1_i2c_irq(int irqno, void *dev_id)
+{
+ struct ma35d1_i2c *i2c = dev_id;
+ unsigned long status;
+
+ status = readl(i2c->regs + MA35_STATUS0);
+
+ if (status == MA35_M_ARB_LOST) {
+ dev_err(i2c->dev, "Arbitration lost\n");
+ ma35d1_i2c_stop(i2c, -EAGAIN);
+ goto out;
+ }
+
+ else if (status == MA35_BUS_ERROR) {
+ dev_err(i2c->dev, "Bus error during transfer\n");
+ ma35d1_i2c_stop(i2c, -EIO);
+ goto out;
+ }
+
+ if (ma35d1_is_controller_status(status))
+ i2c_ma35d1_irq_controller_trx(i2c, status);
+ else
+ i2c_ma35d1_irq_target_trx(i2c, status);
+
+out:
+ return IRQ_HANDLED;
+}
+
+static int ma35d1_i2c_doxfer(struct ma35d1_i2c *i2c, struct i2c_msg *msgs,
+ int num)
+{
+ unsigned long timeout;
+ unsigned int val;
+ int ret, err;
+
+ i2c->msg = msgs;
+ i2c->msg_num = num;
+ i2c->msg_ptr = 0;
+ i2c->msg_idx = 0;
+ i2c->err = 0;
+
+ ma35d1_i2c_enable_irq(i2c);
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_STA_SI);
+ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+ ma35d1_i2c_disable_irq(i2c);
+ ret = i2c->msg_idx;
+
+ if (timeout == 0) {
+ dev_dbg(i2c->dev, "xfer timeout\n");
+ ret = -ETIMEDOUT;
+ goto reset;
+ }
+
+ err = readl_poll_timeout(i2c->regs + MA35_CTL0, val,
+ !(val & MA35_CTL_STO), 100,
+ STOP_TIMEOUT_MS * 10000);
+ if (err) {
+ dev_err(i2c->dev, "bus idle timeout\n");
+ ret = -EBUSY;
+ goto reset;
+ } else if (i2c->err) {
+ dev_dbg(i2c->dev, "xfer error %d\n", i2c->err);
+ ret = i2c->err;
+ } else if (ret != num) {
+ dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
+ }
+ return ret;
+
+reset:
+ ma35d1_i2c_reset(i2c);
+ return ret;
+}
+
+static int ma35d1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct ma35d1_i2c *i2c = i2c_get_adapdata(adap);
+ int retry, ret;
+
+ ret = pm_runtime_resume_and_get(i2c->dev);
+ if (ret)
+ return ret;
+
+ for (retry = 0; retry < adap->retries; retry++) {
+ ret = ma35d1_i2c_doxfer(i2c, msgs, num);
+ if (ret != -EAGAIN)
+ break;
+
+ dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);
+ fsleep(100);
+ }
+
+ if (ret == -EAGAIN)
+ ret = -EREMOTEIO;
+
+ if (i2c->target) {
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI_AA);
+ ma35d1_i2c_enable_irq(i2c);
+ }
+ pm_runtime_put_autosuspend(i2c->dev);
+
+ return ret;
+}
+
+static int ma35d1_reg_target(struct i2c_client *target)
+{
+ struct ma35d1_i2c *i2c = i2c_get_adapdata(target->adapter);
+ unsigned int val, slvaddr;
+ int ret;
+
+ if (i2c->target)
+ return -EBUSY;
+
+ if (target->flags & I2C_CLIENT_TEN)
+ return -EAFNOSUPPORT;
+
+ ret = pm_runtime_resume_and_get(i2c->dev);
+ if (ret) {
+ dev_err(i2c->dev, "failed to resume i2c controller\n");
+ return ret;
+ }
+
+ ma35d1_i2c_enable_irq(i2c);
+
+ i2c->target = target;
+
+ val = readl(i2c->regs + MA35_CTL0);
+ val |= MA35_CTL_I2CEN;
+ writel(val, i2c->regs + MA35_CTL0);
+ slvaddr = target->addr << 1;
+ writel(slvaddr, i2c->regs + MA35_ADDR0);
+
+ /* I2C enter SLV mode */
+ ma35d1_i2c_write_CTL(i2c, MA35_CTL_SI_AA);
+
+ return 0;
+}
+
+static int ma35d1_unreg_target(struct i2c_client *target)
+{
+ struct ma35d1_i2c *i2c = i2c_get_adapdata(target->adapter);
+ unsigned int val;
+ int ret;
+
+ if (!i2c->target)
+ return -EINVAL;
+
+ /* Disable I2C interrupt */
+ ma35d1_i2c_disable_irq(i2c);
+
+ /* Disable I2C */
+ val = readl(i2c->regs + MA35_CTL0);
+ val &= ~MA35_CTL_I2CEN;
+ writel(val, i2c->regs + MA35_CTL0);
+
+ i2c->target = NULL;
+
+ ret = pm_runtime_put_sync(i2c->dev);
+ if (ret < 0)
+ dev_err(i2c->dev, "failed to suspend i2c controller");
+
+ return 0;
+}
+
+/* Declare Our I2C Functionality */
+static u32 ma35d1_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* I2C Bus Registration Info */
+static const struct i2c_algorithm ma35d1_i2c_algorithm = {
+ .xfer = ma35d1_i2c_xfer,
+ .functionality = ma35d1_i2c_func,
+ .reg_target = ma35d1_reg_target,
+ .unreg_target = ma35d1_unreg_target,
+};
+
+static int ma35d1_i2c_probe(struct platform_device *pdev)
+{
+ struct ma35d1_i2c *i2c;
+ struct resource *res;
+ int ret, clkdiv;
+ unsigned int busfreq;
+ struct device *dev = &pdev->dev;
+
+ i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+ init_waitqueue_head(&i2c->wait);
+
+ i2c->dev = dev;
+
+ i2c->clk = devm_clk_get_prepared(dev, NULL);
+ if (IS_ERR(i2c->clk))
+ return dev_err_probe(dev, PTR_ERR(i2c->clk),
+ "failed to get core clk\n");
+
+ i2c->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(i2c->regs))
+ return PTR_ERR(i2c->regs);
+
+ i2c->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+ if (IS_ERR(i2c->rst))
+ return dev_err_probe(dev, PTR_ERR(i2c->rst),
+ "failed to get reset control\n");
+
+ /* Setup info block for the I2C core */
+ strscpy(i2c->adap.name, "ma35d1-i2c", sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &ma35d1_i2c_algorithm;
+ i2c->adap.retries = 2;
+ i2c->adap.algo_data = i2c;
+ i2c->adap.dev.parent = &pdev->dev;
+ i2c->adap.dev.of_node = pdev->dev.of_node;
+ i2c_set_adapdata(&i2c->adap, i2c);
+
+ /* Default to 100kHz if not specified in DT */
+ busfreq = 100000;
+ device_property_read_u32(dev, "clock-frequency", &busfreq);
+
+ /* Calculate divider based on the current peripheral clock rate */
+ clkdiv = DIV_ROUND_CLOSEST(clk_get_rate(i2c->clk), busfreq * 4) - 1;
+ if (clkdiv < 0 || clkdiv > 0xffff)
+ return dev_err_probe(dev, -EINVAL, "invalid clkdiv value: %d\n",
+ clkdiv);
+
+ i2c->irq = platform_get_irq(pdev, 0);
+ if (i2c->irq < 0)
+ return dev_err_probe(dev, i2c->irq, "failed to get irq\n");
+
+ platform_set_drvdata(pdev, i2c);
+
+ pm_runtime_set_autosuspend_delay(dev, I2C_PM_TIMEOUT_MS);
+ pm_runtime_use_autosuspend(dev);
+ devm_pm_runtime_enable(dev);
+
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to resume device\n");
+
+ writel(FIELD_PREP(MA35_CLKDIV_MSK, clkdiv), i2c->regs + MA35_CLKDIV);
+
+ ret = devm_request_irq(dev, i2c->irq, ma35d1_i2c_irq, 0, dev_name(dev),
+ i2c);
+ if (ret) {
+ dev_err_probe(dev, ret, "cannot claim IRQ %d\n", i2c->irq);
+ goto rpm_put;
+ }
+
+ ret = devm_i2c_add_adapter(dev, &i2c->adap);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to add bus to i2c core\n");
+ goto rpm_put;
+ }
+
+ pm_runtime_put_autosuspend(dev);
+
+ dev_info(&i2c->adap.dev, "%08llx MA35D1 I2C adapter registered\n",
+ res->start);
+ return 0;
+
+rpm_put:
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_put_sync(dev);
+ pm_runtime_disable(dev);
+ return ret;
+}
+
+static int ma35d1_i2c_suspend(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+
+ /* Prepare for wake-up from I2C events if target mode is active */
+ if (i2c->target) {
+ val = readl(i2c->regs + MA35_CTL0);
+ val |= (MA35_CTL_SI | MA35_CTL_AA);
+ writel(val, i2c->regs + MA35_CTL0);
+
+ /* Setup wake-up control */
+ writel(0x1, i2c->regs + MA35_WKCTL);
+
+ /* Clear pending wake-up flags */
+ val = readl(i2c->regs + MA35_WKSTS);
+ writel(val, i2c->regs + MA35_WKSTS);
+
+ enable_irq_wake(i2c->irq);
+
+ ma35d1_i2c_enable_irq(i2c);
+ }
+
+ return 0;
+}
+
+static int ma35d1_i2c_resume(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+
+ if (i2c->target) {
+ /* Disable wake-up */
+ writel(0x0, i2c->regs + MA35_WKCTL);
+
+ /* Clear pending wake-up flags */
+ val = readl(i2c->regs + MA35_WKSTS);
+ writel(val, i2c->regs + MA35_WKSTS);
+
+ disable_irq_wake(i2c->irq);
+ }
+ return 0;
+}
+
+static int ma35d1_i2c_runtime_suspend(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+
+ /* Disable I2C controller */
+ val = readl(i2c->regs + MA35_CTL0);
+ val &= ~MA35_CTL_I2CEN;
+ writel(val, i2c->regs + MA35_CTL0);
+
+ clk_disable(i2c->clk);
+
+ return 0;
+}
+
+static int ma35d1_i2c_runtime_resume(struct device *dev)
+{
+ struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ ret = clk_enable(i2c->clk);
+ if (ret) {
+ dev_err(dev, "failed to enable clock in resume\n");
+ return ret;
+ }
+
+ /* Enable I2C controller */
+ val = readl(i2c->regs + MA35_CTL0);
+ val |= MA35_CTL_I2CEN;
+ writel(val, i2c->regs + MA35_CTL0);
+
+ return 0;
+}
+
+static const struct dev_pm_ops ma35d1_i2c_pmops = {
+ SYSTEM_SLEEP_PM_OPS(ma35d1_i2c_suspend, ma35d1_i2c_resume)
+ RUNTIME_PM_OPS(ma35d1_i2c_runtime_suspend,
+ ma35d1_i2c_runtime_resume, NULL)
+};
+
+static const struct of_device_id ma35d1_i2c_of_match[] = {
+ { .compatible = "nuvoton,ma35d1-i2c" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ma35d1_i2c_of_match);
+
+static struct platform_driver ma35d1_i2c_driver = {
+ .probe = ma35d1_i2c_probe,
+ .driver = {
+ .name = "ma35d1-i2c",
+ .of_match_table = ma35d1_i2c_of_match,
+ .pm = pm_ptr(&ma35d1_i2c_pmops),
+ },
+};
+module_platform_driver(ma35d1_i2c_driver);
+
+MODULE_AUTHOR("Zi-Yu Chen <zychennvt@gmail.com>");
+MODULE_DESCRIPTION("MA35D1 I2C Bus Driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related
* [PATCH v4 1/3] dt-bindings: i2c: nuvoton,ma35d1-i2c: Add MA35D1 I2C controller
From: Zi-Yu Chen @ 2026-06-10 3:02 UTC (permalink / raw)
To: Andi Shyti
Cc: Jacky Huang, Shan-Chun Hung, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-i2c, devicetree,
linux-arm-kernel, linux-kernel, Zi-Yu Chen, Krzysztof Kozlowski
In-Reply-To: <20260610030208.2020275-1-zychennvt@gmail.com>
Add device tree binding documentation for the I2C controller
found in the Nuvoton MA35D1 SoC.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Zi-Yu Chen <zychennvt@gmail.com>
---
.../bindings/i2c/nuvoton,ma35d1-i2c.yaml | 63 +++++++++++++++++++
1 file changed, 63 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
diff --git a/Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml b/Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
new file mode 100644
index 000000000000..f2c004049d86
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/nuvoton,ma35d1-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 I2C Controller
+
+maintainers:
+ - Zi-Yu Chen <zychennvt@gmail.com>
+
+description:
+ The Nuvoton MA35D1 I2C controller supports controller and optional target mode.
+
+allOf:
+ - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+ compatible:
+ const: nuvoton,ma35d1-i2c
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-frequency:
+ description:
+ Desired I2C bus clock frequency in Hz. The absence of this property
+ indicates the default frequency 100 kHz.
+
+ resets:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - resets
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+ #include <dt-bindings/reset/nuvoton,ma35d1-reset.h>
+
+ i2c0: i2c@40800000 {
+ compatible = "nuvoton,ma35d1-i2c";
+ reg = <0x40800000 0x1000>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk I2C0_GATE>;
+ clock-frequency = <100000>;
+ resets = <&sys MA35D1_RESET_I2C0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v4 0/3] i2c: ma35d1: Add support for MA35D1 I2C controller
From: Zi-Yu Chen @ 2026-06-10 3:02 UTC (permalink / raw)
To: Andi Shyti
Cc: Jacky Huang, Shan-Chun Hung, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-i2c, devicetree,
linux-arm-kernel, linux-kernel, Zi-Yu Chen
This series adds support for the I2C controller found in the Nuvoton
MA35D1 SoC. The driver supports controller and optional target mode
and runtime power management.
The implementation has been tested on the Nuvoton MA35D1 SOM board.
Changes in v4:
- Patch 1 (dt-bindings):
- Update example interrupt number.
- Patch 2 (driver):
- Remove redundant spinlocks and fix 'irq' type to signed.
- Fix target address recovery in ma35d1_i2c_reset().
- Refactor IRQ handler for multi-msg reads and NACK/IGNORE_NAK.
- Fix timeout UAF via explicit IRQ disabling during recovery.
- Drop IRQF_SHARED and fix PM paths in probe/unregistration.
- Limit suspend/resume wakeup logic to target mode only.
- Patch 3 (dts):
- Add missing i2c0 node to dtsi.
- Switch SoM configuration from i2c1 to i2c2 with updated pinctrl.
- Add nau8822 audio codec node under i2c2 on the SoM board.
- Drop redundant i2c0 alias and clean up dtsi property ordering.
v3: https://lore.kernel.org/r/20260512073953.564323-1-zychennvt@gmail.com/
Changes in v3:
- Fix minor DTS formatting issues (whitespace, missing newline)
v2: https://lore.kernel.org/r/20260316063726.41048-1-zychennvt@gmail.com
Changes in v2:
- Overall:
- Rebase on linux-i2c/i2c-next
- Switched terminology from "master/slave" to "controller/target".
- Patch 1 (dt-bindings):
- Simplified description and fixed 'reg' size in example.
- Patch 2 (driver):
- Modernized using devm_*, generic device properties, and FIELD_PREP/GENMASK.
- Optimized power management by moving clock control to runtime PM.
- Simplified code by removing redundant .remove(), .owner, and inlines.
- Added dev_err_probe() and default bus frequency handling.
- Patch 3 (dts):
- Moved i2c aliases to board dts and reordered nodes alphabetically.
v1: https://lore.kernel.org/r/20260302020822.13936-1-zychennvt@gmail.com
Zi-Yu Chen (3):
dt-bindings: i2c: nuvoton,ma35d1-i2c: Add MA35D1 I2C controller
i2c: ma35d1: Add Nuvoton MA35D1 I2C driver support
arm64: dts: nuvoton: Add I2C nodes for MA35D1 SoC
.../bindings/i2c/nuvoton,ma35d1-i2c.yaml | 63 ++
.../boot/dts/nuvoton/ma35d1-som-256m.dts | 20 +
arch/arm64/boot/dts/nuvoton/ma35d1.dtsi | 72 ++
drivers/i2c/busses/Kconfig | 13 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-ma35d1.c | 778 ++++++++++++++++++
6 files changed, 947 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/nuvoton,ma35d1-i2c.yaml
create mode 100644 drivers/i2c/busses/i2c-ma35d1.c
--
2.34.1
^ permalink raw reply
* Re: [PATCH v3] cpu/hotplug: Fix NULL kobject warning in cpuhp_smt_enable()
From: Jinjie Ruan @ 2026-06-10 2:44 UTC (permalink / raw)
To: Catalin Marinas
Cc: Will Deacon, corbet, skhan, punit.agrawal, jic23,
osama.abdelkader, chenl311, fengchengwen, suzuki.poulose, maz,
lpieralisi, timothy.hayes, sascha.bischoff, arnd,
mrigendra.chaubey, pierre.gondois, dietmar.eggemann, yangyicong,
sudeep.holla, linux-arm-kernel, linux-doc, linux-kernel
In-Reply-To: <aihUPsuEytsM6Dly@arm.com>
On 6/10/2026 1:58 AM, Catalin Marinas wrote:
> Hi Jinjie,
>
> On Wed, Jun 03, 2026 at 02:38:11PM +0800, Jinjie Ruan wrote:
>> On 6/2/2026 7:09 PM, Will Deacon wrote:
>>> On Wed, May 20, 2026 at 10:20:23AM +0800, Jinjie Ruan wrote:
>>>> When booting with ACPI, arm64 smp_prepare_cpus() currently sets all
>>>> enumerated CPUs as "present" regardless of their status in the MADT. This
>>>> causes issues with SMT hotplug control. For instance, with QEMU's
>>>> "-smp 4,maxcpus=8" configuration, the MADT GICC entries are populated as
>>>> follows: the first four CPUs are marked Enabled while the remaining four
>>>> are marked Online Capable to support potential hot-plugging.
>>>>
>>>> Fix this by:
>>>>
>>>> 1. When booting with ACPI, checking the ACPI_MADT_ENABLED flag in the GICC
>>>> entry before calling set_cpu_present() during SMP initialization.
>>>>
>>>> 2. Properly managing the present mask in acpi_map_cpu() and
>>>> acpi_unmap_cpu() to support actual CPU hotplug events, This aligns with
>>>> other architectures like x86 and LoongArch.
>>>>
>>>> 3. Update the arm64 CPU hotplug documentation to no longer state that all
>>>> online-capable vCPUs are marked as present by the kernel at boot time.
>>>>
>>>> This ensures that only physically available or explicitly enabled CPUs
>>>> are in the present mask, keeping the SMT control logic consistent with
>>>> the actual hardware state.
>>>
>>> Please can you check the Sashiko review comment?
>>>
>>> https://sashiko.dev/#/patchset/20260520022023.126670-1-ruanjinjie@huawei.com
>>
>> I think commit eba4675008a6 ("arm64: arch_register_cpu() variant to
>> check if an ACPI handle is now available.") introduced this bug.
>>
>> It introduced an architectural safety block inside
>> arch_unregister_cpu(). If a hot-unplug operation is determined to be a
>> physical hardware removal (where _STA evaluates to
>> !ACPI_STA_DEVICE_PRESENT), it aborts the unregistration transaction
>> early to protect unreadied arm64 infrastructure, thereby skipping
>> unregister_cpu().
>>
>> However, the generic ACPI processor driver path in
>> acpi_processor_post_eject() currently treats arch_unregister_cpu() as
>> an unconditional void operation. When arch_unregister_cpu() bails out
>> early, the subsequent cleanup flow blindly proceeds to call
>> acpi_unmap_cpu(), clears global per-cpu processor arrays, and
>> unconditionally free the 'struct acpi_processor' object.
>>
>> I think we can fix this by:
>>
>> 1. Refactoring arch_unregister_cpu() to return an integer
>> transaction status. It returns -EOPNOTSUPP when aborting due to physical
>> hot-remove blocking, -EINVAL/-EIO on firmware failures, and 0 only upon
>> successful unregistration.
>>
>> 2. Guarding the downstream execution flow in
>> acpi_processor_post_eject(). If arch_unregister_cpu() returns a error
>> code, the hot-unplug transaction is considered aborted.
>
> I wonder whether we need all this guarding. In the worst case, we could
> rewrite the function, something like below, to always unregister and
> only warn:
>
> void arch_unregister_cpu(int cpu)
> {
> acpi_handle acpi_handle = acpi_get_processor_handle(cpu);
> struct cpu *c = &per_cpu(cpu_devices, cpu);
> acpi_status status;
> unsigned long long sta;
>
> if (!acpi_handle) {
> pr_err_once("Removing a CPU without associated ACPI handle\n");
> } else {
> status = acpi_evaluate_integer(acpi_handle, "_STA", NULL, &sta);
> if (!ACPI_FAILURE(status) &&
> cpu_present(cpu) && !(sta & ACPI_STA_DEVICE_PRESENT))
> pr_err_once("Changing CPU present bit is not supported\n");
> }
>
> unregister_cpu(c);
> }
>
> However, on the first condition, can we actually trigger !acpi_handle?
> If not, we could just drop it. I tried to look up the paths and I don't
> think we'd ever end up in this function with !acpi_handle. So this
> leaves us with the next checks.
You are absolutely right:
Source Binding: During the CPU hot-add phase, acpi_add_single_object()
directly binds a valid firmware handle to device->handle, which is then
stored into per_cpu(processors, cpu) via acpi_processor_add().
Identical Lifecycle: When the hot-unplug path later invokes
acpi_get_processor_handle(), it retrieves the exact same active
pr->handle managed by the ACPI device framework, guaranteeing that the
returned handle is never NULL as long as the device exists.
648 static struct acpi_scan_handler processor_handler = {
649 >-------.ids = processor_device_ids,
650 >-------.attach = acpi_processor_add,
651 #ifdef CONFIG_ACPI_HOTPLUG_CPU
652 >-------.post_eject = acpi_processor_post_eject,
653 #endif
654 >-------.hotplug = {
655 >------->-------.enabled = true,
656 >-------},
657 };
acpi_bus_scan()
-> acpi_bus_check_add()
-> acpi_add_single_object(&device, handle, type, !first_pass)
-> acpi_init_device_object()
-> device->handle = handle
acpi_processor_hotadd_init()
-> acpi_processor_set_per_cpu(pr, device)
-> per_cpu(processors, pr->id) = pr
acpi_processor_add()
-> pr->handle = device->handle
acpi_get_processor_handle()
-> pr = per_cpu(processors, cpu)
-> return pr->handle
>
> On the second/third conditions, it's more about preventing physical CPU
> hotplug as we haven't properly defined it for arm yet but we could just
> add a WARN_ONCE() to make it more visible and still proceed with the
> unregistering. I think with your proposal, we don't fully unroll the
Agreed. Unregistering the CPU is absolutely necessary at this stage
since we cannot fully roll back the state anyway, and adding a
WARN_ONCE() is more than sufficient to flag unsupported physical CPU
hot-unplug on ARM64 for now.
> state anyway just by returning an error in arch_unregister_cpu(), so I'd
> rather continue here.
Exactly. Achieving a perfect rollback at this stage is extremely
difficult and clean-up is rarely complete. It is much simpler and more
robust to just force the unregistration and carry on, which is also
consistent with how other architectures handle this by basically blindly
unregistering the CPU anyway.
>
> What does firmware do for virtual CPU hotplug w.r.t. _STA? I noticed a
> slight change in wording in the cpu-hotplug.rst doc with your patch from
>
> On virtual systems the _STA method must always report the CPU as
> ``present``
>
> to
>
> On virtual systems the _STA method must report the CPU as ``present``
> when it is activated by the firmware
>
> Was your intention that _STA.PRESENT can become 0 when hot-unplugging
> virtual CPUs?
Sorry, that was not the intention but a mistake. On ARM64 virtual
systems, _STA.PRESENT will always remain 1 even when a vCPU is
hot-unplugged.Due to ARM64 architectural constraints (such as the GICv3
Redistributor and KVM vGIC configuration which must be statically sized
at boot), virtual CPU hotplug is emulated by keeping all possible vCPUs
present in the system, while toggling their availability via the
_STA.ENABLED bit.
Expose below ACPI Status to Guest kernel:
a. Always _STA.Present=1 (all possible vCPUs)
b. _STA.Enabled=1 (plugged vCPUs)
c. _STA.Enabled=0 (unplugged vCPUs)
Link: https://lists.gnu.org/archive/html/qemu-devel/2025-05/msg05076.html
>
^ permalink raw reply
* [PATCH] ARM: boot/compressed: adjust Acorn font display code for added header
From: Ethan Nelson-Moore @ 2026-06-10 2:46 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: Ethan Nelson-Moore, Russell King, stable, Greg Kroah-Hartman,
Simona Vetter, Peilin Ye
Commit 6735b4632def ("Fonts: Support FONT_EXTRA_WORDS macros for
built-in fonts") added a header to the data for built-in fonts.
However, the Acorn font display code in the ARM decompressor was never
adjusted to account for the added offset to the raw data, causing the
font to display incorrectly. Resolve this issue by adding the
appropriate offset when referring to the font data variable.
Fixes: 6735b4632def ("Fonts: Support FONT_EXTRA_WORDS macros for built-in fonts")
Reported-by: Russell King <linux@armlinux.org.uk>
Closes: https://lore.kernel.org/all/aifhAn2RMdxQ2p86@shell.armlinux.org.uk/
Cc: stable@vger.kernel.org # 5.10+
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
---
arch/arm/boot/compressed/ll_char_wr.S | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/compressed/ll_char_wr.S b/arch/arm/boot/compressed/ll_char_wr.S
index 1ec8cb2898b1..7f218e938865 100644
--- a/arch/arm/boot/compressed/ll_char_wr.S
+++ b/arch/arm/boot/compressed/ll_char_wr.S
@@ -21,7 +21,8 @@
LC0: .word LC0
.word bytes_per_char_h
.word video_size_row
- .word acorndata_8x8
+ @ The offset ensures that the header is skipped
+ .word acorndata_8x8 + 4 /* FONT_EXTRA_WORDS */ * 4 /* sizeof(int) */
.word con_charconvtable
/*
--
2.43.0
^ permalink raw reply related
* Re: [RFC PATCH v2 1/3] mm/huge_memory: make persistent huge zero folio read-only
From: Lance Yang @ 2026-06-10 2:15 UTC (permalink / raw)
To: akpm
Cc: xueyuan.chen21, linux-mm, linux-kernel, linux-arm-kernel, x86,
catalin.marinas, will, tglx, mingo, bp, dave.hansen, luto, peterz,
hpa, david, ljs, liam, vbabka, rppt, surenb, mhocko, ziy,
baolin.wang, npache, ryan.roberts, dev.jain, baohua, lance.yang,
yang, jannh, dave.hansen
In-Reply-To: <20260609124549.aff7e774603c4af188009408@linux-foundation.org>
On Tue, Jun 09, 2026 at 12:45:49PM -0700, Andrew Morton wrote:
>On Tue, 9 Jun 2026 22:37:59 +0800 Xueyuan Chen <xueyuan.chen21@gmail.com> wrote:
>
>> The huge zero folio is shared globally, and its contents should never
>> change after initialization. As Jann Horn pointed out[1], the kernel has
>> had bugs, including security bugs, where read-only pages were later written
>> to. If the persistent huge zero folio is read-only in the direct map, such
>> writes fault instead of silently corrupting the shared zero contents.
>>
>> Add arch_make_pages_readonly() so mm code can request read-only direct-map
>> protection for a page range. Direct-map protection is
>> architecture-specific, so the generic weak implementation does nothing.
>>
>> This was inspired by Jann Horn's read-only zero page work[1] and follow-up
>> discussion[2] with Yang Shi.
>>
>> [1] https://lore.kernel.org/linux-mm/20260508-ro-zeropage-v1-1-9808abc20b49@google.com/
>> [2] https://lore.kernel.org/linux-mm/CAHbLzkrXXe7r3n3jXgDKtwZhRqj=jDx9E6dLOULohnhBguvi9A@mail.gmail.com/
>>
>> ...
>>
>> --- a/mm/huge_memory.c
>> +++ b/mm/huge_memory.c
>> @@ -308,6 +308,11 @@ static unsigned long shrink_huge_zero_folio_scan(struct shrinker *shrink,
>> return 0;
>> }
>>
>> +bool __weak arch_make_pages_readonly(struct page *page, int nr_pages)
>> +{
>> + return false;
>> +}
>> +
>> static struct shrinker *huge_zero_folio_shrinker;
>>
>> #ifdef CONFIG_SYSFS
>> @@ -982,8 +987,14 @@ static int __init thp_shrinker_init(void)
>> * that get_huge_zero_folio() will most likely not fail as
>> * thp_shrinker_init() is invoked early on during boot.
>> */
>> - if (!get_huge_zero_folio())
>> + if (!get_huge_zero_folio()) {
>> pr_warn("Allocating persistent huge zero folio failed\n");
>> + return 0;
>> + }
>> +
>> + arch_make_pages_readonly(folio_page(huge_zero_folio, 0),
>> + HPAGE_PMD_NR);
>
>Can it simply pass the folio?
Right, this came from the RFC v1 discussion[1]. David preferred a page-
range helper for possible future non-folio callers, not something folio-
only.
Of course, we could also add a folio wrapper on top of that if needed :)
[1] https://lore.kernel.org/linux-mm/929875a2-9e94-4dbc-9c98-b342ccc3f4e2@kernel.org/
Thanks, Lance
^ permalink raw reply
* Re: [PATCHv2 4/4] serial: mxs-auart: fix IRQ registration ordering and manage console clock
From: Frank Li @ 2026-06-10 1:32 UTC (permalink / raw)
To: Rosen Penev
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
open list:TTY LAYER AND SERIAL DRIVERS,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20260609223717.41670-5-rosenp@gmail.com>
On Tue, Jun 09, 2026 at 03:37:17PM -0700, Rosen Penev wrote:
> Move the main UART IRQ registration after uart_add_one_port so that
> s->port.state and s->port.lock are initialized before the interrupt
> handler can run. Mask all UART interrupts before adding the port to
> prevent spurious IRQs left by the bootloader.
Please use seperate patch to this problem only.
Frank
>
> After probe succeeds, disable the module clock for non-console ports
> since startup will re-enable it on port open. For console ports, keep
> the clock prepared so auart_console_write() can safely call
> clk_enable() from atomic context.
>
> Guard the IRQ handler and get_mctrl with clk_enable/clk_disable since
> GPIO IRQs and serial-core status queries can fire while the clock is
> disabled for non-console ports.
>
> In remove, disable the clock for console ports to balance the enable
> done in probe, preventing a clock leak on unbind.
>
> Assisted-by: opencode:big-pickle
> ---
> drivers/tty/serial/mxs-auart.c | 49 +++++++++++++++++++++++++++-------
> 1 file changed, 39 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
> index 4499e3206e85..e2b656638ab3 100644
> --- a/drivers/tty/serial/mxs-auart.c
> +++ b/drivers/tty/serial/mxs-auart.c
> @@ -738,9 +738,13 @@ static u32 mxs_auart_modem_status(struct mxs_auart_port *s, u32 mctrl)
> static u32 mxs_auart_get_mctrl(struct uart_port *u)
> {
> struct mxs_auart_port *s = to_auart_port(u);
> - u32 stat = mxs_read(s, REG_STAT);
> + u32 stat;
> u32 mctrl = 0;
>
> + clk_enable(s->clk);
> + stat = mxs_read(s, REG_STAT);
> + clk_disable(s->clk);
> +
> if (stat & AUART_STAT_CTS)
> mctrl |= TIOCM_CTS;
>
> @@ -1079,6 +1083,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
> struct mxs_auart_port *s = context;
> u32 mctrl_temp = s->mctrl_prev;
>
> + clk_enable(s->clk);
> uart_port_lock(&s->port);
>
> stat = mxs_read(s, REG_STAT);
> @@ -1118,6 +1123,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
> }
>
> uart_port_unlock(&s->port);
> + clk_disable(s->clk);
>
> return IRQ_HANDLED;
> }
> @@ -1603,10 +1609,6 @@ static int mxs_auart_probe(struct platform_device *pdev)
> }
>
> s->port.irq = irq;
> - ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0,
> - dev_name(&pdev->dev), s);
> - if (ret)
> - goto out_disable_clk;
>
> platform_set_drvdata(pdev, s);
>
> @@ -1627,9 +1629,28 @@ static int mxs_auart_probe(struct platform_device *pdev)
>
> mxs_auart_reset_deassert(s);
>
> + /* Mask all UART interrupts to prevent spurious IRQs from bootloader */
> + mxs_write(0, s, REG_INTR);
> +
> ret = uart_add_one_port(&auart_driver, &s->port);
> - if (ret)
> - goto out_free_qpio_irq;
> + if (ret) {
> + auart_port[s->port.line] = NULL;
> + goto out_disable_clk;
> + }
> +
> + /*
> + * Request the main IRQ after uart_add_one_port so that
> + * s->port.state and s->port.lock are initialized before
> + * the handler can run in response to a bootloader-left
> + * interrupt.
> + */
> + ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0,
> + dev_name(&pdev->dev), s);
> + if (ret) {
> + uart_remove_one_port(&auart_driver, &s->port);
> + auart_port[s->port.line] = NULL;
> + goto out_disable_clk;
> + }
>
> /* ASM9260 don't have version reg */
> if (is_asm9260_auart(s)) {
> @@ -1641,10 +1662,16 @@ static int mxs_auart_probe(struct platform_device *pdev)
> (version >> 16) & 0xff, version & 0xffff);
> }
>
> - return 0;
> + /*
> + * Disable clock -- startup will re-enable when the port is opened.
> + * For the console port the clock must stay prepared so that
> + * auart_console_write() can safely call clk_enable() from
> + * atomic context.
> + */
> + if (!uart_console(&s->port))
> + clk_disable_unprepare(s->clk);
>
> -out_free_qpio_irq:
> - auart_port[s->port.line] = NULL;
> + return 0;
>
> out_disable_clk:
> clk_disable_unprepare(s->clk);
> @@ -1657,6 +1684,8 @@ static void mxs_auart_remove(struct platform_device *pdev)
>
> uart_remove_one_port(&auart_driver, &s->port);
> auart_port[s->port.line] = NULL;
> + if (uart_console(&s->port))
> + clk_disable_unprepare(s->clk);
> }
>
> static struct platform_driver mxs_auart_driver = {
> --
> 2.54.0
>
>
^ permalink raw reply
* [PATCH net-next v8 6/6] riscv: dts: eswin: eic7700-hifive-premier-p550: enable Ethernet controller
From: lizhi2 @ 2026-06-10 1:32 UTC (permalink / raw)
To: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee, Zhi Li
In-Reply-To: <20260610012727.848-1-lizhi2@eswincomputing.com>
From: Zhi Li <lizhi2@eswincomputing.com>
Enable the on-board Gigabit Ethernet controller on the
HiFive Premier P550 development board.
Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
---
.../dts/eswin/eic7700-hifive-premier-p550.dts | 240 ++++++++++++++++++
arch/riscv/boot/dts/eswin/eic7700.dtsi | 105 ++++++++
2 files changed, 345 insertions(+)
diff --git a/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts b/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts
index 131ed1fc6b2e..edd91b04e251 100644
--- a/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts
+++ b/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts
@@ -13,11 +13,251 @@ / {
aliases {
serial0 = &uart0;
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
};
chosen {
stdout-path = "serial0:115200n8";
};
+
+ vcc_1v8: vcc1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+};
+
+&xtal24m {
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal24m";
+};
+
+&pinctrl {
+ status = "okay";
+ vrgmii-supply = <&vcc_1v8>;
+
+ pinctrl_gpio0: gpio0-grp {
+ gpio0-pins {
+ pins = "gpio0";
+ function = "gpio";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio5: gpio5-grp {
+ gpio5-pins {
+ pins = "gpio5";
+ function = "gpio";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio11: gpio11-grp {
+ gpio11-pins {
+ pins = "gpio11";
+ function = "gpio";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio14: gpio14-grp {
+ gpio14-pins {
+ pins = "mode_set1";
+ function = "gpio";
+ input-disable;
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_gpio15: gpio15-grp {
+ gpio15-pins {
+ pins = "mode_set2";
+ function = "gpio";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio28: gpio28-grp {
+ gpio28-pins {
+ pins = "gpio28";
+ function = "gpio";
+ input-enable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio43: gpio43-grp {
+ gpio43-pins {
+ pins = "usb1_pwren";
+ function = "gpio";
+ input-disable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio71: gpio71-grp {
+ gpio71-pins {
+ pins = "mipi_csi0_xhs";
+ function = "gpio";
+ input-disable;
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_gpio74: gpio74-grp {
+ gpio74-pins {
+ pins = "mipi_csi1_xhs";
+ function = "gpio";
+ input-disable;
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_gpio76: gpio76-grp {
+ gpio76-pins {
+ pins = "mipi_csi2_xvs";
+ function = "gpio";
+ input-disable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio77: gpio77-grp {
+ gpio77-pins {
+ pins = "mipi_csi2_xhs";
+ function = "gpio";
+ input-disable;
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_gpio79: gpio79-grp {
+ gpio79-pins {
+ pins = "mipi_csi3_xvs";
+ function = "gpio";
+ input-disable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio80: gpio80-grp {
+ gpio80-pins {
+ pins = "mipi_csi3_xhs";
+ function = "gpio";
+ input-disable;
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_gpio82: gpio82-grp {
+ gpio82-pins {
+ pins = "mipi_csi4_xvs";
+ function = "gpio";
+ input-disable;
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_gpio84: gpio84-grp {
+ gpio84-pins {
+ pins = "mipi_csi4_mclk";
+ function = "gpio";
+ input-disable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio85: gpio85-grp {
+ gpio85-pins {
+ pins = "mipi_csi5_xvs";
+ function = "gpio";
+ input-disable;
+ bias-pull-up;
+ };
+ };
+
+ pinctrl_gpio94: gpio94-grp {
+ gpio94-pins {
+ pins = "s_mode";
+ function = "gpio";
+ input-disable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio106: gpio106-grp {
+ gpio106-pins {
+ pins = "gpio106";
+ function = "gpio";
+ input-disable;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio111: gpio111-grp {
+ gpio111-pins {
+ pins = "gpio111";
+ function = "gpio";
+ input-disable;
+ bias-disable;
+ };
+ };
+};
+
+&gmac0 {
+ phy-handle = <&gmac0_phy0>;
+ phy-mode = "rgmii-id";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio106>;
+ rx-internal-delay-ps = <20>;
+ tx-internal-delay-ps = <100>;
+ status = "okay";
+};
+
+&gmac0_mdio {
+ gmac0_phy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0>;
+ reset-gpios = <&gpioD 10 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ };
+};
+
+&gmac1 {
+ phy-handle = <&gmac1_phy0>;
+ /*
+ * The MAC silicon unconditionally introduces an ~2 ns TX clock-to-data
+ * skew (MAC-side TX internal delay). The PHY provides the standard
+ * ~2 ns RX internal delay. The driver additionally inverts the RX
+ * clock at 1000 Mb/s to correct a silicon RX sampling timing issue.
+ * phy-mode is "rgmii-id": TX delay from the MAC silicon, RX delay
+ * from the PHY.
+ */
+ phy-mode = "rgmii-id";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio111>;
+ rx-internal-delay-ps = <200>;
+ tx-internal-delay-ps = <2200>;
+ status = "okay";
+};
+
+&gmac1_mdio {
+ gmac1_phy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0>;
+ reset-gpios = <&gpioD 15 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <80000>;
+ };
};
&uart0 {
diff --git a/arch/riscv/boot/dts/eswin/eic7700.dtsi b/arch/riscv/boot/dts/eswin/eic7700.dtsi
index c3ed93008bca..c77bc8b1b7bc 100644
--- a/arch/riscv/boot/dts/eswin/eic7700.dtsi
+++ b/arch/riscv/boot/dts/eswin/eic7700.dtsi
@@ -5,6 +5,9 @@
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/reset/eswin,eic7700-reset.h>
+
/ {
#address-cells = <2>;
#size-cells = <2>;
@@ -202,6 +205,11 @@ pmu {
<0x00000000 0x0000000f 0xfffffffc 0x000000ff 0x00000078>;
};
+ xtal24m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+
soc {
compatible = "simple-bus";
ranges;
@@ -245,6 +253,85 @@ plic: interrupt-controller@c000000 {
#interrupt-cells = <1>;
};
+ hsp_power_domain: bus@50400000 {
+ compatible = "simple-pm-bus";
+ ranges;
+ clocks = <&clk 171>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ hsp_sp_csr: hsp-sp-top-csr@50440000 {
+ compatible = "eswin,eic7700-syscfg", "syscon";
+ reg = <0x0 0x50440000 0x0 0x2000>;
+ };
+
+ gmac0: ethernet@50400000 {
+ compatible = "eswin,eic7700-qos-eth",
+ "snps,dwmac-5.20";
+ reg = <0x0 0x50400000 0x0 0x10000>;
+ interrupts = <61>;
+ interrupt-names = "macirq";
+ clocks = <&clk 186>,
+ <&clk 171>,
+ <&clk 40>,
+ <&clk 193>;
+ clock-names = "axi", "cfg", "stmmaceth", "tx";
+ resets = <&reset EIC7700_RESET_HSP_ETH0_ARST>;
+ reset-names = "stmmaceth";
+ eswin,hsp-sp-csr = <&hsp_sp_csr 0x100 0x108 0x118 0x114 0x11c>;
+ snps,aal;
+ snps,fixed-burst;
+ snps,tso;
+ snps,axi-config = <&stmmac_axi_setup_gmac0>;
+ status = "disabled";
+
+ gmac0_mdio: mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ stmmac_axi_setup_gmac0: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <2>;
+ snps,wr_osr_lmt = <2>;
+ };
+ };
+
+ gmac1: ethernet@50410000 {
+ compatible = "eswin,eic7700-qos-eth-clk-inversion",
+ "snps,dwmac-5.20";
+ reg = <0x0 0x50410000 0x0 0x10000>;
+ interrupts = <70>;
+ interrupt-names = "macirq";
+ clocks = <&clk 186>,
+ <&clk 171>,
+ <&clk 40>,
+ <&clk 194>;
+ clock-names = "axi", "cfg", "stmmaceth", "tx";
+ resets = <&reset EIC7700_RESET_HSP_ETH1_ARST>;
+ reset-names = "stmmaceth";
+ eswin,hsp-sp-csr = <&hsp_sp_csr 0x200 0x208 0x218 0x214 0x21c>;
+ snps,aal;
+ snps,fixed-burst;
+ snps,tso;
+ snps,axi-config = <&stmmac_axi_setup_gmac1>;
+ status = "disabled";
+
+ gmac1_mdio: mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ stmmac_axi_setup_gmac1: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <2>;
+ snps,wr_osr_lmt = <2>;
+ };
+ };
+ };
+
uart0: serial@50900000 {
compatible = "snps,dw-apb-uart";
reg = <0x0 0x50900000 0x0 0x10000>;
@@ -341,5 +428,23 @@ gpioD: gpio-port@3 {
#gpio-cells = <2>;
};
};
+
+ pinctrl: pinctrl@51600080 {
+ compatible = "eswin,eic7700-pinctrl";
+ reg = <0x0 0x51600080 0x0 0x1fff80>;
+ };
+
+ clk: clock-controller@51828000 {
+ compatible = "eswin,eic7700-clock";
+ reg = <0x0 0x51828000 0x0 0x300>;
+ clocks = <&xtal24m>;
+ #clock-cells = <1>;
+ };
+
+ reset: reset-controller@51828300 {
+ compatible = "eswin,eic7700-reset";
+ reg = <0x0 0x51828300 0x0 0x200>;
+ #reset-cells = <1>;
+ };
};
};
--
2.25.1
^ permalink raw reply related
* [PATCH net-next v8 5/6] dt-bindings: mfd: syscon: add ESWIN EIC7700 compatible
From: lizhi2 @ 2026-06-10 1:32 UTC (permalink / raw)
To: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee, Zhi Li, Conor Dooley
In-Reply-To: <20260610012727.848-1-lizhi2@eswincomputing.com>
From: Zhi Li <lizhi2@eswincomputing.com>
Document ESWIN EIC7700 SoC compatible for syscon registers.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
---
Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index e22867088063..7d3365601249 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -62,6 +62,7 @@ select:
- cirrus,ep7209-syscon3
- cnxt,cx92755-uc
- econet,en751221-chip-scu
+ - eswin,eic7700-syscfg
- freecom,fsg-cs2-system-controller
- fsl,imx93-aonmix-ns-syscfg
- fsl,imx93-wakeupmix-syscfg
@@ -175,6 +176,7 @@ properties:
- cirrus,ep7209-syscon3
- cnxt,cx92755-uc
- econet,en751221-chip-scu
+ - eswin,eic7700-syscfg
- freecom,fsg-cs2-system-controller
- fsl,imx93-aonmix-ns-syscfg
- fsl,imx93-wakeupmix-syscfg
--
2.25.1
^ permalink raw reply related
* [PATCH net-next v8 4/6] net: stmmac: eic7700: add support for eth1 clock inversion variant
From: lizhi2 @ 2026-06-10 1:31 UTC (permalink / raw)
To: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee, Zhi Li
In-Reply-To: <20260610012727.848-1-lizhi2@eswincomputing.com>
From: Zhi Li <lizhi2@eswincomputing.com>
The eth1 MAC exhibits silicon-inherent RX and TX timing behavior that
differs from the eth0 implementation.
At 1000Mbps, RX sampling requires clock inversion due to a fixed MAC
input skew that cannot be compensated by standard RGMII delay settings.
The TX path includes a fixed ~2ns internal delay introduced by the MAC
silicon. This delay is always present and is already accounted for in
the device tree tx-internal-delay-ps property as part of the effective
output timing.
The tx-internal-delay-ps property describes the effective delay seen at
the MAC output. Since the hardware register controls only the
programmable portion of the delay, the driver subtracts the fixed
silicon-inherent component before programming the delay register.
Use compatible-specific match data to identify the eth1 variant and
apply RX clock inversion only at 1000Mbps.
The PHY interface mode is adjusted via phy_fix_phy_mode_for_mac_delays()
to avoid double-application of RGMII delays when MAC-side delays are
already present.
Link speed dependency means RX sampling configuration is applied in the
fix_mac_speed callback after negotiation.
No behavior changes for the existing eth0 controller.
Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
---
.../ethernet/stmicro/stmmac/dwmac-eic7700.c | 107 +++++++++++++++++-
1 file changed, 101 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
index ec99b597aeaf..34a394a20570 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
@@ -29,10 +29,14 @@
/*
* TX/RX Clock Delay Bit Masks:
* - TX Delay: bits [14:8] — TX_CLK delay (unit: 0.02ns per bit)
+ * - TX Invert : bit [15]
* - RX Delay: bits [30:24] — RX_CLK delay (unit: 0.02ns per bit)
+ * - RX Invert : bit [31]
*/
#define EIC7700_ETH_TX_ADJ_DELAY GENMASK(14, 8)
#define EIC7700_ETH_RX_ADJ_DELAY GENMASK(30, 24)
+#define EIC7700_ETH_TX_INV_DELAY BIT(15)
+#define EIC7700_ETH_RX_INV_DELAY BIT(31)
#define EIC7700_MAX_DELAY_STEPS 0x7F
#define EIC7700_DELAY_STEP_PS 20
@@ -43,7 +47,14 @@ static const char * const eic7700_clk_names[] = {
"tx", "axi", "cfg",
};
+struct eic7700_dwmac_data {
+ bool rgmii_rx_clk_invert;
+ bool has_internal_tx_delay;
+ u32 tx_clk_inherent_skew_ps;
+};
+
struct eic7700_qos_priv {
+ struct device *dev;
struct plat_stmmacenet_data *plat_dat;
struct regmap *eic7700_hsp_regmap;
u32 eth_axi_lp_ctrl_offset;
@@ -54,6 +65,7 @@ struct eic7700_qos_priv {
u32 eth_clk_dly_param;
bool has_txd_offset;
bool has_rxd_offset;
+ bool eth_rx_clk_inv;
};
static int eic7700_clks_config(void *priv, bool enabled)
@@ -97,9 +109,6 @@ static int eic7700_dwmac_init(struct device *dev, void *priv)
if (dwc->has_rxd_offset)
regmap_write(dwc->eic7700_hsp_regmap, dwc->eth_rxd_offset, 0);
- regmap_write(dwc->eic7700_hsp_regmap, dwc->eth_clk_offset,
- dwc->eth_clk_dly_param);
-
return 0;
}
@@ -126,8 +135,38 @@ static int eic7700_dwmac_resume(struct device *dev, void *priv)
return ret;
}
+/*
+ * eth1 requires RX clock inversion at 1000Mbps due to silicon-inherent
+ * RX sampling skew at MAC input.
+ *
+ * The configuration is updated in fix_mac_speed() because the required
+ * sampling behavior depends on the negotiated link speed.
+ */
+static void eic7700_dwmac_fix_speed(void *priv, phy_interface_t interface,
+ int speed, unsigned int mode)
+{
+ struct eic7700_qos_priv *dwc = (struct eic7700_qos_priv *)priv;
+ u32 dly_param = dwc->eth_clk_dly_param;
+
+ switch (speed) {
+ case SPEED_1000:
+ if (dwc->eth_rx_clk_inv)
+ dly_param |= EIC7700_ETH_RX_INV_DELAY;
+ break;
+ case SPEED_100:
+ case SPEED_10:
+ break;
+ default:
+ dev_warn(dwc->dev, "unsupported speed %u\n", speed);
+ return;
+ }
+
+ regmap_write(dwc->eic7700_hsp_regmap, dwc->eth_clk_offset, dly_param);
+}
+
static int eic7700_dwmac_probe(struct platform_device *pdev)
{
+ const struct eic7700_dwmac_data *data;
struct plat_stmmacenet_data *plat_dat;
struct stmmac_resources stmmac_res;
struct eic7700_qos_priv *dwc_priv;
@@ -148,6 +187,30 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
if (!dwc_priv)
return -ENOMEM;
+ dwc_priv->dev = &pdev->dev;
+
+ data = device_get_match_data(&pdev->dev);
+ if (!data)
+ return dev_err_probe(&pdev->dev,
+ -EINVAL, "no match data found\n");
+
+ dwc_priv->eth_rx_clk_inv = data->rgmii_rx_clk_invert;
+ /*
+ * The MAC silicon unconditionally adds ~2 ns TX delay; prevent
+ * the PHY from also adding TX delay to avoid doubling it.
+ *
+ * DT specifies rgmii-id (TX from MAC silicon, RX from PHY);
+ * override to rgmii-rxid so the PHY only adds its RX delay.
+ */
+ if (data->has_internal_tx_delay) {
+ plat_dat->phy_interface =
+ phy_fix_phy_mode_for_mac_delays(plat_dat->phy_interface,
+ true, false);
+ if (plat_dat->phy_interface == PHY_INTERFACE_MODE_NA)
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "phy interface mode is NA\n");
+ }
+
/* Read rx-internal-delay-ps and update rx_clk delay */
if (!of_property_read_u32(pdev->dev.of_node,
"rx-internal-delay-ps", &delay_ps)) {
@@ -167,7 +230,13 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
FIELD_PREP(EIC7700_ETH_RX_ADJ_DELAY, val);
}
- /* Read tx-internal-delay-ps and update tx_clk delay */
+ /* Read tx-internal-delay-ps and update tx_clk delay.
+ *
+ * For eswin,eic7700-qos-eth-clk-inversion, the DT property describes
+ * the effective TX delay at the MAC output, including the inherent
+ * silicon delay. Subtract the fixed component to obtain the
+ * programmable delay value.
+ */
if (!of_property_read_u32(pdev->dev.of_node,
"tx-internal-delay-ps", &delay_ps)) {
if (delay_ps % EIC7700_DELAY_STEP_PS)
@@ -175,9 +244,16 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
"tx delay must be multiple of %dps\n",
EIC7700_DELAY_STEP_PS);
+ if (delay_ps < data->tx_clk_inherent_skew_ps)
+ return dev_err_probe(&pdev->dev, -EINVAL,
+ "tx delay %ups below inherent skew %ups\n",
+ delay_ps, data->tx_clk_inherent_skew_ps);
+
+ delay_ps -= data->tx_clk_inherent_skew_ps;
+
if (delay_ps > EIC7700_MAX_DELAY_PS)
return dev_err_probe(&pdev->dev, -EINVAL,
- "tx delay out of range\n");
+ "tx delay out of programmable range\n");
val = delay_ps / EIC7700_DELAY_STEP_PS;
@@ -254,12 +330,31 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
plat_dat->exit = eic7700_dwmac_exit;
plat_dat->suspend = eic7700_dwmac_suspend;
plat_dat->resume = eic7700_dwmac_resume;
+ plat_dat->fix_mac_speed = eic7700_dwmac_fix_speed;
return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
}
+static const struct eic7700_dwmac_data eic7700_dwmac_data = {
+ .rgmii_rx_clk_invert = false,
+ .has_internal_tx_delay = false,
+ .tx_clk_inherent_skew_ps = 0,
+};
+
+static const struct eic7700_dwmac_data eic7700_dwmac_data_clk_inversion = {
+ .rgmii_rx_clk_invert = true,
+ .has_internal_tx_delay = true,
+ .tx_clk_inherent_skew_ps = 2000,
+};
+
static const struct of_device_id eic7700_dwmac_match[] = {
- { .compatible = "eswin,eic7700-qos-eth" },
+ { .compatible = "eswin,eic7700-qos-eth",
+ .data = &eic7700_dwmac_data,
+ },
+ {
+ .compatible = "eswin,eic7700-qos-eth-clk-inversion",
+ .data = &eic7700_dwmac_data_clk_inversion,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, eic7700_dwmac_match);
--
2.25.1
^ permalink raw reply related
* [PATCH net-next v8 3/6] net: stmmac: eic7700: make RGMII delay properties optional
From: lizhi2 @ 2026-06-10 1:29 UTC (permalink / raw)
To: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee, Zhi Li
In-Reply-To: <20260610012727.848-1-lizhi2@eswincomputing.com>
From: Zhi Li <lizhi2@eswincomputing.com>
Make rx-internal-delay-ps and tx-internal-delay-ps optional in the
EIC7700 DWMAC driver.
The driver previously required both properties to be present and would
fail probe when they were missing. This restricts valid hardware
configurations where RGMII timing is instead provided by the PHY or
board design.
Update the driver to treat missing delay properties as zero delay,
allowing systems without explicit MAC-side delay tuning to operate
correctly.
This aligns the driver behavior with the updated device tree binding
and provides a safe default configuration when MAC-side delay
programming is not required.
Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
index 4ac979d874d6..ec99b597aeaf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
@@ -165,9 +165,6 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
dwc_priv->eth_clk_dly_param &= ~EIC7700_ETH_RX_ADJ_DELAY;
dwc_priv->eth_clk_dly_param |=
FIELD_PREP(EIC7700_ETH_RX_ADJ_DELAY, val);
- } else {
- return dev_err_probe(&pdev->dev, -EINVAL,
- "missing required property rx-internal-delay-ps\n");
}
/* Read tx-internal-delay-ps and update tx_clk delay */
@@ -187,9 +184,6 @@ static int eic7700_dwmac_probe(struct platform_device *pdev)
dwc_priv->eth_clk_dly_param &= ~EIC7700_ETH_TX_ADJ_DELAY;
dwc_priv->eth_clk_dly_param |=
FIELD_PREP(EIC7700_ETH_TX_ADJ_DELAY, val);
- } else {
- return dev_err_probe(&pdev->dev, -EINVAL,
- "missing required property tx-internal-delay-ps\n");
}
dwc_priv->eic7700_hsp_regmap =
--
2.25.1
^ permalink raw reply related
* [PATCH net-next v8 2/6] dt-bindings: ethernet: eswin: add EIC7700 eth1 RX clock inversion variant
From: lizhi2 @ 2026-06-10 1:29 UTC (permalink / raw)
To: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee, Zhi Li
In-Reply-To: <20260610012727.848-1-lizhi2@eswincomputing.com>
From: Zhi Li <lizhi2@eswincomputing.com>
The EIC7700 SoC integrates two GMAC instances. The eth1 MAC exhibits
different RX clock sampling characteristics due to silicon-inherent
timing behavior.
The eth1 MAC has a fixed, non-configurable RX clock-to-data skew at the
MAC input in the order of 4-5 ns. This cannot be compensated solely by
the standard MAC internal delay configuration and PHY delay, and RX clock
inversion is required at 1000Mbps for correct sampling.
The eth1 TX path also includes a fixed silicon-inherent delay of
approximately 2 ns. This delay is always present and cannot be disabled.
It is therefore part of the effective transmit timing observed on the
wire.
For the eth1 variant, the valid tx-internal-delay-ps values include
this fixed delay component. Consequently, the effective range becomes
2000-4540 ps (approximately 2000 ps fixed delay plus 0-2540 ps
programmable delay).
Introduce a dedicated compatible string
"eswin,eic7700-qos-eth-clk-inversion" to represent the eth1 variant,
allowing the driver to apply RX clock inversion only when required by
hardware variant selection.
This keeps SoC-level differentiation without exposing silicon-fixed skew
as configurable device tree parameters.
Add per-compatible tx-internal-delay-ps constraints using a oneOf
schema partition:
- eswin,eic7700-qos-eth: 0-2540 ps
- eswin,eic7700-qos-eth-clk-inversion: 2000-4540 ps
No functional change for existing "eswin,eic7700-qos-eth" users.
Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
---
.../bindings/net/eswin,eic7700-eth.yaml | 55 +++++++++++++++++--
1 file changed, 49 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
index 4e02fedae5c6..8cb7545c56e8 100644
--- a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
+++ b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
@@ -20,16 +20,38 @@ select:
contains:
enum:
- eswin,eic7700-qos-eth
+ - eswin,eic7700-qos-eth-clk-inversion
required:
- compatible
allOf:
- $ref: snps,dwmac.yaml#
+oneOf:
+ - properties:
+ compatible:
+ contains:
+ const: eswin,eic7700-qos-eth
+ tx-internal-delay-ps:
+ minimum: 0
+ maximum: 2540
+ multipleOf: 20
+
+ - properties:
+ compatible:
+ contains:
+ const: eswin,eic7700-qos-eth-clk-inversion
+ tx-internal-delay-ps:
+ minimum: 2000
+ maximum: 4540
+ multipleOf: 20
+
properties:
compatible:
items:
- - const: eswin,eic7700-qos-eth
+ - enum:
+ - eswin,eic7700-qos-eth
+ - eswin,eic7700-qos-eth-clk-inversion
- const: snps,dwmac-5.20
reg:
@@ -67,11 +89,6 @@ properties:
maximum: 2540
multipleOf: 20
- tx-internal-delay-ps:
- minimum: 0
- maximum: 2540
- multipleOf: 20
-
eswin,hsp-sp-csr:
description:
HSP CSR is to control and get status of different high-speed peripherals
@@ -140,3 +157,29 @@ examples:
snps,wr_osr_lmt = <2>;
};
};
+
+ ethernet@50410000 {
+ compatible = "eswin,eic7700-qos-eth-clk-inversion", "snps,dwmac-5.20";
+ reg = <0x50410000 0x10000>;
+ interrupt-parent = <&plic>;
+ interrupts = <70>;
+ interrupt-names = "macirq";
+ clocks = <&d0_clock 186>, <&d0_clock 171>, <&d0_clock 40>,
+ <&d0_clock 194>;
+ clock-names = "axi", "cfg", "stmmaceth", "tx";
+ resets = <&reset 94>;
+ reset-names = "stmmaceth";
+ eswin,hsp-sp-csr = <&hsp_sp_csr 0x200 0x208 0x218 0x214 0x21c>;
+ phy-handle = <&gmac1_phy0>;
+ phy-mode = "rgmii-id";
+ snps,aal;
+ snps,fixed-burst;
+ snps,tso;
+ snps,axi-config = <&stmmac_axi_setup_gmac1>;
+
+ stmmac_axi_setup_gmac1: stmmac-axi-config {
+ snps,blen = <0 0 0 0 16 8 4>;
+ snps,rd_osr_lmt = <2>;
+ snps,wr_osr_lmt = <2>;
+ };
+ };
--
2.25.1
^ permalink raw reply related
* [PATCH net-next v8 1/6] dt-bindings: ethernet: eswin: relax internal delay model to range-based constraints
From: lizhi2 @ 2026-06-10 1:28 UTC (permalink / raw)
To: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee, Zhi Li
In-Reply-To: <20260610012727.848-1-lizhi2@eswincomputing.com>
From: Zhi Li <lizhi2@eswincomputing.com>
Relax internal delay constraints for EIC7700 Ethernet binding.
Replace fixed enumeration of rx-internal-delay-ps and tx-internal-delay-ps
with a range-based definition (0-2540 ps, 20 ps steps) to reflect actual
hardware capability.
Mark rx/tx internal delay properties as optional, as they are board-
specific tuning parameters rather than mandatory configuration.
Update the device tree example to align with the relaxed constraint model
and remove delay properties from the example to avoid implying they are
required.
No functional change to existing DT users.
Signed-off-by: Zhi Li <lizhi2@eswincomputing.com>
---
.../bindings/net/eswin,eic7700-eth.yaml | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
index 65882ff79d8d..4e02fedae5c6 100644
--- a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
+++ b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
@@ -63,10 +63,14 @@ properties:
- const: stmmaceth
rx-internal-delay-ps:
- enum: [0, 200, 600, 1200, 1600, 1800, 2000, 2200, 2400]
+ minimum: 0
+ maximum: 2540
+ multipleOf: 20
tx-internal-delay-ps:
- enum: [0, 200, 600, 1200, 1600, 1800, 2000, 2200, 2400]
+ minimum: 0
+ maximum: 2540
+ multipleOf: 20
eswin,hsp-sp-csr:
description:
@@ -105,8 +109,6 @@ required:
- phy-mode
- resets
- reset-names
- - rx-internal-delay-ps
- - tx-internal-delay-ps
- eswin,hsp-sp-csr
unevaluatedProperties: false
@@ -116,23 +118,22 @@ examples:
ethernet@50400000 {
compatible = "eswin,eic7700-qos-eth", "snps,dwmac-5.20";
reg = <0x50400000 0x10000>;
- clocks = <&d0_clock 186>, <&d0_clock 171>, <&d0_clock 40>,
- <&d0_clock 193>;
- clock-names = "axi", "cfg", "stmmaceth", "tx";
interrupt-parent = <&plic>;
interrupts = <61>;
interrupt-names = "macirq";
- phy-mode = "rgmii-id";
- phy-handle = <&phy0>;
+ clocks = <&d0_clock 186>, <&d0_clock 171>, <&d0_clock 40>,
+ <&d0_clock 193>;
+ clock-names = "axi", "cfg", "stmmaceth", "tx";
resets = <&reset 95>;
reset-names = "stmmaceth";
- rx-internal-delay-ps = <200>;
- tx-internal-delay-ps = <200>;
eswin,hsp-sp-csr = <&hsp_sp_csr 0x100 0x108 0x118 0x114 0x11c>;
- snps,axi-config = <&stmmac_axi_setup>;
+ phy-handle = <&phy0>;
+ phy-mode = "rgmii-id";
snps,aal;
snps,fixed-burst;
snps,tso;
+ snps,axi-config = <&stmmac_axi_setup>;
+
stmmac_axi_setup: stmmac-axi-config {
snps,blen = <0 0 0 0 16 8 4>;
snps,rd_osr_lmt = <2>;
--
2.25.1
^ permalink raw reply related
* [PATCH net-next v8 0/6] net: stmmac: eic7700: add eth1 variant support and update delay bindings
From: lizhi2 @ 2026-06-10 1:27 UTC (permalink / raw)
To: devicetree, andrew+netdev, davem, edumazet, kuba, robh, krzk+dt,
conor+dt, netdev, pabeni, mcoquelin.stm32, alexandre.torgue,
rmk+kernel, pjw, palmer, aou, alex, linux-riscv, linux-stm32,
linux-arm-kernel, linux-kernel, maxime.chevallier
Cc: ningyu, linmin, pinkesh.vaghela, pritesh.patel, weishangjuan,
horms, lee, Zhi Li
From: Zhi Li <lizhi2@eswincomputing.com>
v7 -> v8:
- eth0-related fixes were moved into separate series [1], [2]:
- All eth0-related fixes have been removed from this series to avoid mixing
MAC variants and RX timing logic in a single review context.
- Reference:
[1]https://lore.kernel.org/lkml/20260602014528.2076-1-lizhi2@eswincomputing.com/
[2]https://lore.kernel.org/lkml/20260518021919.404-1-lizhi2@eswincomputing.com/
- Update cover letter and overall series scope description:
- Replace previous wording "EIC7700 eth1 RX sampling timing fix"
with a more accurate description:
- Add eth1 MAC variant support.
- Update RGMII delay binding model.
- This reflects the structural nature of the series rather than a pure
bug fix.
- Split DT bindings changes into two patches:
- patch1:
- Relax RGMII internal delay constraints.
- Change rx/tx internal delay from enum-based model to range-based
model.
- Mark delay properties as optional.
- patch2:
- Introduce EIC7700 eth1 MAC variant compatible string
"eswin,eic7700-qos-eth-clk-inversion".
- Model silicon-specific RX clock inversion requirement via SoC
variant instead of board-level properties.
- Due to this restructuring:
- Patch structure and commit messages have changed significantly
compared to v7.
- The previously received Acked-by from Conor Dooley is not
carried forward because the binding patches were substantially
reworked and split.
- Split driver changes into two patches. No functional changes to eth1
compared to v7:
- patch 3:
- Make rx-internal-delay-ps and tx-internal-delay-ps optional.
- Remove mandatory DT property requirement in probe path.
- Allow zero-delay default when properties are absent.
- patch 4:
- Add support for eth1 MAC variant using compatible-specific
match data.
- Introduce RX clock inversion handling for eth1 at runtime.
- Apply speed-dependent configuration via fix_mac_speed()
callback.
- Note:
- These patches (5/6 and 6/6) are included only to facilitate review
of the overall Ethernet integration across bindings, driver, and
device tree.
A cleaned-up, upstream-ready DTS series will be submitted separately
once all dependencies and final hardware integration are completed.
- Link to v7:
https://lore.kernel.org/lkml/20260427072353.1114-1-lizhi2@eswincomputing.com/
v6 -> v7:
- Address checkpatch.pl --strict warnings for DTS changes:
- Split DT binding documentation and DTS board description into separate patches
- Fix DTS style issues reported by checkpatch:
- Reduce line length where applicable
- Add required description for rgmii-rxid
- DTS changes in this series are split into:
- Patch 3/4: syscon binding update (documentation / reference only)
- Patch 4/4: board DTS changes (architecture overview only)
These patches (3/4 and 4/4) are provided to facilitate review of the overall
Ethernet integration across binding, driver, and device tree, and are not
intended as final upstream submission in their current form.
A cleaned-up, upstream-ready DTS series will be submitted separately once
all dependencies and final hardware integration are completed.
- Note:
- Clock-related bindings referenced in earlier revisions are now already merged
into net-next, so dtbs_check warnings related to clock are no longer present
and are not relevant to this revision.
- No functional changes in the stmmac driver or binding semantics in this revision.
- Link to v6:
https://lore.kernel.org/lkml/20260423085501.760-1-lizhi2@eswincomputing.com/
v5 -> v6:
- Update DTS/DTSI descriptions to fix invalid phandle references reported by DTC:
- Add missing GMAC provider nodes required for proper hardware description:
- HSP power domain: GMAC nodes moved under this domain to reflect
hardware power hierarchy.
- Clock nodes: added to provide clk phandles referenced by GMAC.
- Reset nodes: added to provide reset phandles referenced by GMAC.
- Pinctrl nodes: defines pinctrl settings for GMAC signals
(pinctrl_gpio106, pinctrl_gpio111).
- Move GMAC nodes under the correct HSP power domain.
- Ensure DTS builds without dtc errors and all phandle references
(clk/reset/pinctrl/power-domain) are valid.
- This update does not change runtime behavior; it only improves DTS
consistency and resolves issues reported by dtc.
- Note:
- The patch 3/3 for DTS changes in this series provide an overview of the GMAC
integration and its dependencies, as discussed previously:
https://lore.kernel.org/lkml/64bf6b40-b947-4ffa-8d48-4d6341931327@lunn.ch/
- It is **not intended for upstream inclusion** in its current form,
and is provided solely for architecture overview and integration
context.
- A fully cleaned and upstream-ready DTS series will be submitted
separately once all related components (pinctrl, clock, power-domain,
etc.) are finalized.
- dtbs_check has been run on top of net-next for reference purposes.
Remaining warnings are expected due to missing EIC7700 clock bindings[1]
in net-next and do not reflect issues in the DTS design itself.
- One remaining warning:
- eswin,eic7700-clock
- The clock binding has already been applied to upstream and is present
in mainline, but not yet available in net-next.
- The syscon binding is extended in this series to include the
eswin,eic7700-syscfg compatible.
- Any further refinement of the syscfg binding will be handled in
separate patches if needed.
- Dependencies:
- [1]EIC7700 clock binding:
https://lore.kernel.org/lkml/20260303080637.2100-1-dongxuyang@eswincomputing.com/
(already applied to upstream)
- Link to v5:
https://lore.kernel.org/lkml/20260324073017.376-1-lizhi2@eswincomputing.com/
v4 -> v5:
- eswin,eic7700-eth.yaml:
- Add Acked-by from Conor Dooley
- No functional changes
- Update dwmac-eic7700.c:
- Disable clocks on the error path to fix a clock leak in
eic7700_dwmac_init() when regmap_set_bits() fails
(reported by Simon Horman <horms@kernel.org>)
- Link to v4:
https://lore.kernel.org/lkml/20260313075234.1567-1-lizhi2@eswincomputing.com/
v3 -> v4:
- Update eswin,eic7700-eth.yaml:
- Improve commit message in dt-bindings patch to clarify the
hardware difference of the eth1 MAC and why a new compatible
string is required.
- Move the newly added eswin,hsp-sp-csr item to the end of the list
to avoid inserting entries in the middle of the binding schema.
- Simplify the compatible schema by replacing the previous oneOf
construct with an enum.
- Update dwmac-eic7700.c:
- Fix build issues.
- Adjust code to match the updated binding definition.
- Update DTS/DTSI descriptions:
- Move SoC-level descriptions to the .dtsi file.
- Keep board-specific configuration in the .dts file.
- Link to v3:
https://lore.kernel.org/lkml/20260303061525.846-1-lizhi2@eswincomputing.com/
v2 -> v3:
- Update eswin,eic7700-eth.yaml:
- Extend rx-internal-delay-ps and tx-internal-delay-ps range
from 0-2400 to 0-2540 to match the full 7-bit hardware delay
field (127 * 20 ps).
- Add "multipleOf: 20" constraint to reflect the 20 ps hardware
step size.
- Make rx-internal-delay-ps and tx-internal-delay-ps optional.
A well-designed board should not require internal delay tuning.
- Remove rx-internal-delay-ps and tx-internal-delay-ps from the
example to avoid encouraging blind copy into board DTs.
- Update dwmac-eic7700.c:
- Treat rx-internal-delay-ps and tx-internal-delay-ps as optional
DT properties.
- Apply delay configuration only when properties are present.
- Keep TX/RX delay registers cleared by default to ensure a
deterministic state when no delay is specified.
- Describe Ethernet configuration for the HiFive Premier P550 board:
- Add GMAC controller nodes for the HiFive Premier P550 board
to describe the on-board Ethernet configuration.
The Ethernet controller depends on clock, reset, pinctrl
and HSP subsystem providers which are currently under
upstream review. These dependent nodes will be submitted
separately once the corresponding drivers are merged.
Due to these missing dependencies, dt-binding-check may
report warnings or failures for this series.
- No functional changes to RX clock inversion logic.
- Link to v2:
https://lore.kernel.org/lkml/20260209094628.886-1-lizhi2@eswincomputing.com/
- This series is based on the EIC7700 clock support series:
https://lore.kernel.org/all/20260210095008.726-1-dongxuyang@eswincomputing.com/
The clock series is currently under review.
v1 -> v2:
- Update eswin,eic7700-eth.yaml:
- Drop the vendor-specific properties eswin,rx-clk-invert and
eswin,tx-clk-invert.
- Introduce a distinct compatible string
"eswin,eic7700-qos-eth-clk-inversion" to describe MAC instances that
require internal RGMII clock inversion.
This models the SoC-specific hardware difference directly via the
compatible string and avoids per-board configuration properties.
- Change rx-internal-delay-ps and tx-internal-delay-ps from enum to
minimum/maximum to reflect the actual delay range (0-2400 ps)
- Add reference to High-Speed Subsystem documentation in eswin,hsp-sp-csr
description. The HSP CSR block is described in Chapter 10
("High-Speed Interface") of the EIC7700X SoC Technical Reference Manual,
Part 4 (EIC7700X_SoC_Technical_Reference_Manual_Part4.pdf):
https://github.com/eswincomputing/EIC7700X-SoC-Technical-Reference-Manual/releases
- Update dwmac-eic7700.c:
- Remove handling of eswin,rx-clk-invert and eswin,tx-clk-invert
properties.
- Select RX clock inversion based on the new
"eswin,eic7700-qos-eth-clk-inversion" compatible string, using
match data to apply the required configuration for affected MAC
instances (eth1).
- Link to v1:
https://lore.kernel.org/lkml/20260109080601.1262-1-lizhi2@eswincomputing.com/
Zhi Li (6):
dt-bindings: ethernet: eswin: relax internal delay model to
range-based constraints
dt-bindings: ethernet: eswin: add EIC7700 eth1 RX clock inversion
variant
net: stmmac: eic7700: make RGMII delay properties optional
net: stmmac: eic7700: add support for eth1 clock inversion variant
dt-bindings: mfd: syscon: add ESWIN EIC7700 compatible
riscv: dts: eswin: eic7700-hifive-premier-p550: enable Ethernet
controller
.../devicetree/bindings/mfd/syscon.yaml | 2 +
.../bindings/net/eswin,eic7700-eth.yaml | 74 ++++--
.../dts/eswin/eic7700-hifive-premier-p550.dts | 240 ++++++++++++++++++
arch/riscv/boot/dts/eswin/eic7700.dtsi | 105 ++++++++
.../ethernet/stmicro/stmmac/dwmac-eic7700.c | 113 ++++++++-
5 files changed, 507 insertions(+), 27 deletions(-)
--
2.25.1
^ permalink raw reply
* [PATCH v6 10/18] KVM: selftests: Add option to set empty routing between IRQs in eventfd IRQ test
From: Sean Christopherson @ 2026-06-10 0:53 UTC (permalink / raw)
To: Paolo Bonzini, Marc Zyngier, Oliver Upton, Sean Christopherson
Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, kvm,
linux-arm-kernel, kvmarm, linux-kernel, David Matlack, Josh Hilke
In-Reply-To: <20260610005338.2967132-1-seanjc@google.com>
From: David Matlack <dmatlack@google.com>
Extend the eventfd IRQ test with an '-e' flag to set empty GSI routing
between interrupts. Clobbering the GSI routing table verifies that KVM
correctly handles CPUx => NULL => CPUy transitions, not just CPUx => CPUy
transitions, and verifies that KVM can "rebuild" an entire routing setup.
Signed-off-by: David Matlack <dmatlack@google.com>
Co-developed-by: Josh Hilke <jrhilke@google.com>
Signed-off-by: Josh Hilke <jrhilke@google.com>
[sean: '-e' for "empty" instead of '-c' for "clear", massage changelog]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/irq_test.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/kvm/irq_test.c b/tools/testing/selftests/kvm/irq_test.c
index 9e2287490262..2ad9efd9abc7 100644
--- a/tools/testing/selftests/kvm/irq_test.c
+++ b/tools/testing/selftests/kvm/irq_test.c
@@ -109,6 +109,13 @@ static void kvm_route_msi(struct kvm_vm *vm, u32 gsi, struct kvm_vcpu *vcpu,
vm_ioctl(vm, KVM_SET_GSI_ROUTING, &routing.header);
}
+static void kvm_set_empty_gsi_routing(struct kvm_vm *vm)
+{
+ struct kvm_irq_routing routing = {};
+
+ vm_ioctl(vm, KVM_SET_GSI_ROUTING, &routing);
+}
+
static const char *probe_iommu_type(void)
{
int io_fd;
@@ -127,11 +134,12 @@ static const char *probe_iommu_type(void)
static void help(const char *name)
{
- printf("Usage: %s [-a] [-d <segment:bus:device.function>] [-h] [-t iommu_type]\n", name);
+ printf("Usage: %s [-a] [-d <segment:bus:device.function>] [-e] [-h] [-t iommu_type]\n", name);
printf("\n");
printf("Tests KVM interrupt routing and delivery via irqfd.\n");
printf("-a Affine the device's host IRQ to a random physical CPU\n");
printf("-d Use a VFIO device to send MSI-X interrupts instead of manually signaling the eventfd\n");
+ printf("-e Set empty GSI routing in-between some interrupts\n");
printf("-t Override the IOMMU type to use (vfio_type1_iommu or iommufd)\n");
printf("\n");
exit(KSFT_FAIL);
@@ -158,6 +166,7 @@ int main(int argc, char **argv)
struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
struct vfio_pci_device *device = NULL;
int nr_irqs = 1000, nr_vcpus = 1;
+ bool set_empty_routing = false;
const char *device_bdf = NULL;
const char *iommu_type = NULL;
int i, j, c, msix, eventfd;
@@ -165,7 +174,7 @@ int main(int argc, char **argv)
struct kvm_vm *vm;
int irq, irq_cpu;
- while ((c = getopt(argc, argv, "ad:ht:")) != -1) {
+ while ((c = getopt(argc, argv, "ad:eht:")) != -1) {
switch (c) {
case 'a':
irq_affinity = true;
@@ -173,6 +182,9 @@ int main(int argc, char **argv)
case 'd':
device_bdf = optarg;
break;
+ case 'e':
+ set_empty_routing = true;
+ break;
case 't':
iommu_type = optarg;
break;
@@ -222,9 +234,13 @@ int main(int argc, char **argv)
}
for (i = 0; i < nr_irqs; i++) {
+ const bool do_set_empty_routing = set_empty_routing && (i & BIT(3));
struct kvm_vcpu *vcpu = vcpus[i % nr_vcpus];
struct timespec start;
+ if (do_set_empty_routing)
+ kvm_set_empty_gsi_routing(vm);
+
kvm_route_msi(vm, gsi, vcpu, vector);
if (irq_affinity) {
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* Re: [PATCHv2 3/4] serial: mxs-auart: use devm resources for iomem and GPIO IRQs
From: Frank Li @ 2026-06-10 1:26 UTC (permalink / raw)
To: Rosen Penev
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
open list:TTY LAYER AND SERIAL DRIVERS,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20260609223717.41670-4-rosenp@gmail.com>
On Tue, Jun 09, 2026 at 03:37:16PM -0700, Rosen Penev wrote:
> Replace platform_get_resource + ioremap with
> devm_platform_get_and_ioremap_resource and convert GPIO IRQ
> request_irq/free_irq to devm_request_irq. This eliminates the
> mxs_auart_free_gpio_irq function and its call sites, and the
> out_iounmap error label. Simplify the remove function accordingly.
as my said before, all function need add ()
Frank
>
> Assisted-by: opencode:big-pickle
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/tty/serial/mxs-auart.c | 53 +++++++---------------------------
> 1 file changed, 11 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
> index aa59a48bfad7..4499e3206e85 100644
> --- a/drivers/tty/serial/mxs-auart.c
> +++ b/drivers/tty/serial/mxs-auart.c
> @@ -1517,15 +1517,6 @@ static int mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev)
> return 0;
> }
>
> -static void mxs_auart_free_gpio_irq(struct mxs_auart_port *s)
> -{
> - enum mctrl_gpio_idx i;
> -
> - for (i = 0; i < UART_GPIO_MAX; i++)
> - if (s->gpio_irq[i] >= 0)
> - free_irq(s->gpio_irq[i], s);
> -}
> -
> static int mxs_auart_request_gpio_irq(struct mxs_auart_port *s)
> {
> int *irq = s->gpio_irq;
> @@ -1537,21 +1528,13 @@ static int mxs_auart_request_gpio_irq(struct mxs_auart_port *s)
> continue;
>
> irq_set_status_flags(irq[i], IRQ_NOAUTOEN);
> - err = request_irq(irq[i], mxs_auart_irq_handle,
> - IRQ_TYPE_EDGE_BOTH, dev_name(s->dev), s);
> + err = devm_request_irq(s->dev, irq[i], mxs_auart_irq_handle,
> + IRQ_TYPE_EDGE_BOTH, dev_name(s->dev), s);
> if (err)
> dev_err(s->dev, "%s - Can't get %d irq\n",
> __func__, irq[i]);
> }
>
> - /*
> - * If something went wrong, rollback.
> - * Be careful: i may be unsigned.
> - */
> - while (err && (i-- > 0))
> - if (irq[i] >= 0)
> - free_irq(irq[i], s);
> -
> return err;
> }
>
> @@ -1596,18 +1579,12 @@ static int mxs_auart_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> - r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - if (!r) {
> - ret = -ENXIO;
> + s->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
> + if (IS_ERR(s->port.membase)) {
> + ret = PTR_ERR(s->port.membase);
> goto out_disable_clk;
> }
> -
> s->port.mapbase = r->start;
> - s->port.membase = ioremap(r->start, resource_size(r));
> - if (!s->port.membase) {
> - ret = -ENOMEM;
> - goto out_disable_clk;
> - }
> s->port.ops = &mxs_auart_ops;
> s->port.iotype = UPIO_MEM;
> s->port.fifosize = MXS_AUART_FIFO_SIZE;
> @@ -1622,21 +1599,21 @@ static int mxs_auart_probe(struct platform_device *pdev)
> irq = platform_get_irq(pdev, 0);
> if (irq < 0) {
> ret = irq;
> - goto out_iounmap;
> + goto out_disable_clk;
> }
>
> s->port.irq = irq;
> ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0,
> dev_name(&pdev->dev), s);
> if (ret)
> - goto out_iounmap;
> + goto out_disable_clk;
>
> platform_set_drvdata(pdev, s);
>
> ret = mxs_auart_init_gpios(s, &pdev->dev);
> if (ret) {
> dev_err(&pdev->dev, "Failed to initialize GPIOs.\n");
> - goto out_iounmap;
> + goto out_disable_clk;
> }
>
> /*
> @@ -1644,7 +1621,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
> */
> ret = mxs_auart_request_gpio_irq(s);
> if (ret)
> - goto out_iounmap;
> + goto out_disable_clk;
>
> auart_port[s->port.line] = s;
>
> @@ -1667,11 +1644,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
> return 0;
>
> out_free_qpio_irq:
> - mxs_auart_free_gpio_irq(s);
> - auart_port[pdev->id] = NULL;
> -
> -out_iounmap:
> - iounmap(s->port.membase);
> + auart_port[s->port.line] = NULL;
>
> out_disable_clk:
> clk_disable_unprepare(s->clk);
> @@ -1683,11 +1656,7 @@ static void mxs_auart_remove(struct platform_device *pdev)
> struct mxs_auart_port *s = platform_get_drvdata(pdev);
>
> uart_remove_one_port(&auart_driver, &s->port);
> - auart_port[pdev->id] = NULL;
> - mxs_auart_free_gpio_irq(s);
> - iounmap(s->port.membase);
> - if (is_asm9260_auart(s))
> - clk_disable_unprepare(s->clk);
> + auart_port[s->port.line] = NULL;
> }
>
> static struct platform_driver mxs_auart_driver = {
> --
> 2.54.0
>
>
^ permalink raw reply
* [PATCH v6 08/18] KVM: selftests: Add a helper to set proc IRQ affinity for IRQ test
From: Sean Christopherson @ 2026-06-10 0:53 UTC (permalink / raw)
To: Paolo Bonzini, Marc Zyngier, Oliver Upton, Sean Christopherson
Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, kvm,
linux-arm-kernel, kvmarm, linux-kernel, David Matlack, Josh Hilke
In-Reply-To: <20260610005338.2967132-1-seanjc@google.com>
From: Josh Hilke <jrhilke@google.com>
Add a utility, proc_irq_set_smp_affinity(), to set the CPU affinity of a
Linux host IRQ via the proc filesystem. Use smp_affinity_list instead of
smp_affinity to avoid having to convert the single CPU to a bitmask.
The helper will be used by the eventfd IRQ test to verify delivery of IRQs
when the affinity is randomized/modified.
Signed-off-by: Josh Hilke <jrhilke@google.com>
[sean: make the utility self-contained, drop "list", massage changelog]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/include/proc_util.h | 2 ++
tools/testing/selftests/kvm/lib/proc_util.c | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/tools/testing/selftests/kvm/include/proc_util.h b/tools/testing/selftests/kvm/include/proc_util.h
index 704839b6d7af..d1ddc967d11d 100644
--- a/tools/testing/selftests/kvm/include/proc_util.h
+++ b/tools/testing/selftests/kvm/include/proc_util.h
@@ -6,4 +6,6 @@
unsigned int vfio_msix_to_host_irq(const char *vfio_device_bdf, int msix);
+void proc_irq_set_smp_affinity(unsigned int irq, int cpu);
+
#endif /* SELFTEST_KVM_PROC_UTIL_H */
diff --git a/tools/testing/selftests/kvm/lib/proc_util.c b/tools/testing/selftests/kvm/lib/proc_util.c
index 84d30f055a0a..3960b3841d63 100644
--- a/tools/testing/selftests/kvm/lib/proc_util.c
+++ b/tools/testing/selftests/kvm/lib/proc_util.c
@@ -38,3 +38,17 @@ unsigned int vfio_msix_to_host_irq(const char *device_bdf, int msix)
return (unsigned int)irq;
}
+void proc_irq_set_smp_affinity(unsigned int irq, int cpu)
+{
+ char path[PATH_MAX];
+ int r, fd;
+
+ snprintf(path, sizeof(path), "/proc/irq/%u/smp_affinity_list", irq);
+ fd = open(path, O_RDWR);
+ TEST_ASSERT(fd >= 0, "Failed to open %s", path);
+
+ r = dprintf(fd, "%d\n", cpu);
+ TEST_ASSERT(r > 0, "Failed to affinitize IRQ-%u to CPU %d", irq, cpu);
+
+ kvm_close(fd);
+}
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* [PATCH v6 05/18] KVM: selftests: Add an irqfd send+receive (and later IRQ bypass) test
From: Sean Christopherson @ 2026-06-10 0:53 UTC (permalink / raw)
To: Paolo Bonzini, Marc Zyngier, Oliver Upton, Sean Christopherson
Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu, kvm,
linux-arm-kernel, kvmarm, linux-kernel, David Matlack, Josh Hilke
In-Reply-To: <20260610005338.2967132-1-seanjc@google.com>
From: David Matlack <dmatlack@google.com>
Add a new test, irq_test to verify that KVM correctly delivers interrupts
to a running vCPU, when triggered via an eventfd bound to a KVM GSI using
KVM's irqfd mechanism.
This test is intentionally simple, for now. Support for sending interrupts
via VFIO devices, for IRQ bypass, and for other features will be added in
the near future.
Add the test in common code, even though it currently will only build and
run on x86, as the concept and the bulk of the host-side code isn't
specific to x86.
Suggested-by: Sean Christopherson <seanjc@google.com>
Link: https://lore.kernel.org/kvm/20250404193923.1413163-68-seanjc@google.com
Signed-off-by: David Matlack <dmatlack@google.com>
Co-developed-by: Josh Hilke <jrhilke@google.com>
Signed-off-by: Josh Hilke <jrhilke@google.com>
[sean: use while() and TEST_ASSERT() instead of if-statement => TEST_FAIL()]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
tools/testing/selftests/kvm/irq_test.c | 170 +++++++++++++++++++++++
2 files changed, 171 insertions(+)
create mode 100644 tools/testing/selftests/kvm/irq_test.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 14316358fd9f..1339228cbf53 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -156,6 +156,7 @@ TEST_GEN_PROGS_x86 += coalesced_io_test
TEST_GEN_PROGS_x86 += dirty_log_perf_test
TEST_GEN_PROGS_x86 += guest_memfd_test
TEST_GEN_PROGS_x86 += hardware_disable_test
+TEST_GEN_PROGS_x86 += irq_test
TEST_GEN_PROGS_x86 += mmu_stress_test
TEST_GEN_PROGS_x86 += rseq_test
TEST_GEN_PROGS_x86 += steal_time
diff --git a/tools/testing/selftests/kvm/irq_test.c b/tools/testing/selftests/kvm/irq_test.c
new file mode 100644
index 000000000000..9f8895b89821
--- /dev/null
+++ b/tools/testing/selftests/kvm/irq_test.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "kvm_util.h"
+#include "test_util.h"
+#include "apic.h"
+#include "processor.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/eventfd.h>
+
+static u64 timeout_ns = 2ULL * 1000 * 1000 * 1000;
+static bool guest_ready_for_irqs[KVM_MAX_VCPUS];
+static bool guest_received_irq[KVM_MAX_VCPUS];
+static bool done;
+
+#define GUEST_RECEIVED_IRQ(__vcpu) \
+ SYNC_FROM_GUEST_AND_READ((__vcpu)->vm, guest_received_irq[(__vcpu)->id])
+
+static u32 guest_get_vcpu_id(void)
+{
+ return x2apic_read_reg(APIC_ID);
+}
+
+static void guest_irq_handler(struct ex_regs *regs)
+{
+ WRITE_ONCE(guest_received_irq[guest_get_vcpu_id()], true);
+
+ x2apic_write_reg(APIC_EOI, 0);
+}
+
+static void guest_code(void)
+{
+ x2apic_enable();
+
+ sti_nop();
+
+ WRITE_ONCE(guest_ready_for_irqs[guest_get_vcpu_id()], true);
+
+ while (!READ_ONCE(done))
+ cpu_relax();
+
+ GUEST_DONE();
+}
+
+static void *vcpu_thread_main(void *arg)
+{
+ struct kvm_vcpu *vcpu = arg;
+ struct ucall uc;
+
+ vcpu_run(vcpu);
+ TEST_ASSERT_EQ(UCALL_DONE, get_ucall(vcpu, &uc));
+
+ return NULL;
+}
+
+static void kvm_route_msi(struct kvm_vm *vm, u32 gsi, struct kvm_vcpu *vcpu,
+ u8 vector)
+{
+ struct {
+ struct kvm_irq_routing header;
+ struct kvm_irq_routing_entry entry;
+ } routing = {
+ .header.nr = 1,
+ .entry = {
+ .gsi = gsi,
+ .type = KVM_IRQ_ROUTING_MSI,
+ .u.msi.address_lo = 0xFEE00000 | (vcpu->id << 12),
+ .u.msi.data = vector,
+ },
+ };
+
+ vm_ioctl(vm, KVM_SET_GSI_ROUTING, &routing.header);
+}
+
+static void help(const char *name)
+{
+ printf("Usage: %s [-h]\n", name);
+ printf("\n");
+ printf("Tests KVM interrupt routing and delivery via irqfd.\n");
+ printf("\n");
+ exit(KSFT_FAIL);
+}
+
+int main(int argc, char **argv)
+{
+ /*
+ * Pick a random vector and a random GSI to use for device IRQ.
+ *
+ * Pick an IRQ vector in range [32, UINT8_MAX]. Min value is 32 because
+ * Linux/x86 reserves vectors 0-31 for exceptions and architecture
+ * defined NMIs and interrupts.
+ *
+ * Pick a GSI in range [24, KVM_MAX_IRQ_ROUTES - 1]. The min value is 24
+ * because KVM reserves GSIs 0-15 for legacy ISA IRQs and 16-23 only go
+ * to the IOAPIC. The max is KVM_MAX_IRQ_ROUTES - 1, because
+ * KVM_MAX_IRQ_ROUTES is exclusive.
+ */
+ u32 gsi = kvm_random_u64_in_range(&kvm_rng, 24, KVM_MAX_IRQ_ROUTES - 1);
+ u8 vector = kvm_random_u64_in_range(&kvm_rng, 32, UINT8_MAX);
+
+ struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
+ pthread_t vcpu_threads[KVM_MAX_VCPUS];
+ int nr_irqs = 1000, nr_vcpus = 1;
+ int i, j, c, eventfd;
+ struct kvm_vm *vm;
+
+ while ((c = getopt(argc, argv, "h")) != -1) {
+ switch (c) {
+ case 'h':
+ default:
+ help(argv[0]);
+ }
+ }
+
+ TEST_REQUIRE(kvm_arch_has_default_irqchip());
+
+ vm = vm_create_with_vcpus(nr_vcpus, guest_code, vcpus);
+ vm_install_exception_handler(vm, vector, guest_irq_handler);
+
+ eventfd = kvm_new_eventfd();
+
+ pr_info("Injecting interrupts for GSI %d (guest vector 0x%x) %d times\n",
+ gsi, vector, nr_irqs);
+
+ kvm_assign_irqfd(vm, gsi, eventfd);
+
+ for (i = 0; i < nr_vcpus; i++)
+ pthread_create(&vcpu_threads[i], NULL, vcpu_thread_main, vcpus[i]);
+
+ for (i = 0; i < nr_vcpus; i++) {
+ struct kvm_vcpu *vcpu = vcpus[i];
+
+ while (!SYNC_FROM_GUEST_AND_READ(vm, guest_ready_for_irqs[vcpu->id]))
+ continue;
+ }
+
+ for (i = 0; i < nr_irqs; i++) {
+ struct kvm_vcpu *vcpu = vcpus[i % nr_vcpus];
+ struct timespec start;
+
+ kvm_route_msi(vm, gsi, vcpu, vector);
+
+ for (j = 0; j < nr_vcpus; j++)
+ TEST_ASSERT(!GUEST_RECEIVED_IRQ(vcpus[j]),
+ "IRQ flag for vCPU %d not clear prior to test",
+ vcpus[j]->id);
+
+ eventfd_write(eventfd, 1);
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ while (!GUEST_RECEIVED_IRQ(vcpu) &&
+ timespec_to_ns(timespec_elapsed(start)) <= timeout_ns)
+ cpu_relax();
+
+ TEST_ASSERT(GUEST_RECEIVED_IRQ(vcpu),
+ "vCPU %d timed out waiting for IRQ (vector 0x%x) from GSI %d\n",
+ vcpu->id, vector, gsi);
+
+ WRITE_AND_SYNC_TO_GUEST(vm, guest_received_irq[vcpu->id], false);
+ }
+
+ WRITE_AND_SYNC_TO_GUEST(vm, done, true);
+
+ for (i = 0; i < nr_vcpus; i++)
+ pthread_join(vcpu_threads[i], NULL);
+
+ return 0;
+}
--
2.54.0.1099.g489fc7bff1-goog
^ permalink raw reply related
* Re: [PATCHv2 2/4] serial: mxs-auart: rework clock handling in mxs_get_clks and probe
From: Frank Li @ 2026-06-10 1:24 UTC (permalink / raw)
To: Rosen Penev
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
open list:TTY LAYER AND SERIAL DRIVERS,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20260609223717.41670-3-rosenp@gmail.com>
On Tue, Jun 09, 2026 at 03:37:15PM -0700, Rosen Penev wrote:
> Use devm_clk_get_enabled for the AHB clock so its enable/disable
> lifetime is managed by the driver model. Move the mod clock
> (clk) prepare_enable out of mxs_get_clks and into probe so that
> clk_set_rate is called while the clock is still disabled, avoiding
> CLK_SET_RATE_GATE failures. Clean up the error labels accordingly.
>
> Assisted-by: opencode:big-pickle
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/tty/serial/mxs-auart.c | 47 ++++++++++++----------------------
> 1 file changed, 17 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
> index de97c0f74e7d..aa59a48bfad7 100644
> --- a/drivers/tty/serial/mxs-auart.c
> +++ b/drivers/tty/serial/mxs-auart.c
> @@ -1470,34 +1470,22 @@ static int mxs_get_clks(struct mxs_auart_port *s,
> return PTR_ERR(s->clk);
> }
>
> - s->clk_ahb = devm_clk_get(s->dev, "ahb");
> + s->clk_ahb = devm_clk_get_enabled(s->dev, "ahb");
> if (IS_ERR(s->clk_ahb)) {
> dev_err(s->dev, "Failed to get \"ahb\" clk\n");
> return PTR_ERR(s->clk_ahb);
> }
>
> - err = clk_prepare_enable(s->clk_ahb);
> - if (err) {
> - dev_err(s->dev, "Failed to enable ahb_clk!\n");
> - return err;
> - }
> -
> + /*
> + * Set mod clock rate while it is still disabled so
> + * CLK_SET_RATE_GATE does not cause clk_set_rate to fail.
> + * The mod clock will be enabled in mxs_auart_startup()
> + * and in probe after mxs_get_clks returns.
> + */
> err = clk_set_rate(s->clk, clk_get_rate(s->clk_ahb));
> - if (err) {
> + if (err)
> dev_err(s->dev, "Failed to set rate!\n");
> - goto disable_clk_ahb;
> - }
>
> - err = clk_prepare_enable(s->clk);
> - if (err) {
> - dev_err(s->dev, "Failed to enable clk!\n");
> - goto disable_clk_ahb;
> - }
> -
> - return 0;
> -
> -disable_clk_ahb:
> - clk_disable_unprepare(s->clk_ahb);
if I understand correct, after apply patch,
if (err)
dev_err(s->dev, ...)
return err;
Perfer method is
if (err)
return dev_err_probe(s->dev, err, ...);
return 0;
Frank
> return err;
> }
>
> @@ -1604,17 +1592,21 @@ static int mxs_auart_probe(struct platform_device *pdev)
> if (ret)
> return ret;
>
> + ret = clk_prepare_enable(s->clk);
> + if (ret)
> + return ret;
> +
> r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> if (!r) {
> ret = -ENXIO;
> - goto out_disable_clks;
> + goto out_disable_clk;
> }
>
> s->port.mapbase = r->start;
> s->port.membase = ioremap(r->start, resource_size(r));
> if (!s->port.membase) {
> ret = -ENOMEM;
> - goto out_disable_clks;
> + goto out_disable_clk;
> }
> s->port.ops = &mxs_auart_ops;
> s->port.iotype = UPIO_MEM;
> @@ -1681,11 +1673,8 @@ static int mxs_auart_probe(struct platform_device *pdev)
> out_iounmap:
> iounmap(s->port.membase);
>
> -out_disable_clks:
> - if (is_asm9260_auart(s)) {
> - clk_disable_unprepare(s->clk);
> - clk_disable_unprepare(s->clk_ahb);
> - }
> +out_disable_clk:
> + clk_disable_unprepare(s->clk);
> return ret;
> }
>
> @@ -1697,10 +1686,8 @@ static void mxs_auart_remove(struct platform_device *pdev)
> auart_port[pdev->id] = NULL;
> mxs_auart_free_gpio_irq(s);
> iounmap(s->port.membase);
> - if (is_asm9260_auart(s)) {
> + if (is_asm9260_auart(s))
> clk_disable_unprepare(s->clk);
> - clk_disable_unprepare(s->clk_ahb);
> - }
> }
>
> static struct platform_driver mxs_auart_driver = {
> --
> 2.54.0
>
>
^ permalink raw reply
* [PATCH v6 2/2] ARM: dts: aspeed: ventura2: Add Meta ventura2 BMC
From: Kyle Hsieh @ 2026-06-10 1:22 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: <20260610-ventura2_initial_dts-v6-0-375d8e9d7ebf@gmail.com>
Add linux device tree entry related to the Meta(Facebook) rmc-node.
The system uses an AT2600 BMC.
This node is named "ventura2".
Signed-off-by: Kyle Hsieh <kylehsieh1995@gmail.com>
---
arch/arm/boot/dts/aspeed/Makefile | 1 +
.../dts/aspeed/aspeed-bmc-facebook-ventura2.dts | 2891 ++++++++++++++++++++
2 files changed, 2892 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..1111daa22f73
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-ventura2.dts
@@ -0,0 +1,2891 @@
+// 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-9 {
+ pwms = <&fanctl1 0 20000>;
+ tach-ch = /bits/ 8 <0x09>;
+ };
+
+ fan-11 {
+ pwms = <&fanctl1 0 20000>;
+ tach-ch = /bits/ 8 <0x0B>;
+ };
+
+ fan-10 {
+ pwms = <&fanctl1 4 20000>;
+ tach-ch = /bits/ 8 <0x0A>;
+ };
+
+ fan-13 {
+ pwms = <&fanctl1 4 20000>;
+ tach-ch = /bits/ 8 <0x0D>;
+ };
+
+ fan-15 {
+ pwms = <&fanctl1 6 20000>;
+ tach-ch = /bits/ 8 <0x0F>;
+ };
+
+ fan-1 {
+ pwms = <&fanctl1 6 20000>;
+ tach-ch = /bits/ 8 <0x01>;
+ };
+
+ fan-0 {
+ pwms = <&fanctl1 10 20000>;
+ tach-ch = /bits/ 8 <0x00>;
+ };
+
+ fan-3 {
+ pwms = <&fanctl1 10 20000>;
+ tach-ch = /bits/ 8 <0x03>;
+ };
+ };
+ };
+ };
+};
+
+&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>;
+
+ 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 v6 1/2] dt-bindings: arm: aspeed: add Meta ventura2 board
From: Kyle Hsieh @ 2026-06-10 1:22 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: <20260610-ventura2_initial_dts-v6-0-375d8e9d7ebf@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 v6 0/2] Add Meta(Facebook) ventura2 BMC(AST2600)
From: Kyle Hsieh @ 2026-06-10 1:22 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 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 | 2891 ++++++++++++++++++++
3 files changed, 2893 insertions(+)
---
base-commit: 9448598b22c50c8a5bb77a9103e2d49f134c9578
change-id: 20251222-ventura2_initial_dts-909b3277d665
Best regards,
--
Kyle Hsieh <kylehsieh1995@gmail.com>
^ permalink raw reply
* Re: [RFC PATCH v3 0/9] accel: rocket: Add RK3568 NPU support
From: Chaoyi Chen @ 2026-06-10 1:14 UTC (permalink / raw)
To: Midgy Balon
Cc: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, joro, will,
robin.murphy, dri-devel, linux-rockchip, devicetree,
linux-arm-kernel, iommu, linux-kernel, Simon Xue, Finley Xiao
In-Reply-To: <CA+GS1Y2-hRqpGgsknh+oOX+-uZ3DZtdekdP9viTP6a40zhhUhg@mail.gmail.com>
Hi Midgy,
On 6/9/2026 7:11 PM, Midgy Balon wrote:
> Hello Chaoyi,
>
> You were right - building rocket as a module fixes it. Thanks for the pointer.
>
> I rebuilt with CONFIG_DRM_ACCEL_ROCKET=m (everything else the same:
> need_regulator on
> the RK3568 NPU power domain via a DOMAIN_M_R variant, domain-supply =
> <&vdd_npu>, and the
> regulator-always-on workaround dropped). The board now boots cleanly
> and, more importantly,
> an NPU job submit no longer hangs: I ran the test workload five times
> with no RCU stall and
> no freeze.
>
> So with rocket=m the need_regulator approach works on RK3568, and I'll
> keep it for v4
> (domain-supply + need_regulator, instead of marking vdd_npu
> always-on). rocket=m is the
> normal configuration anyway; my earlier hang came from building it =y
> in a self-contained
> image, so it probed in the initcalls (around 2 s) and the genpd ->
> I2C-PMIC regulator
> transition ran before the system was ready. As a module it loads from
> udev much later
> (~6.8 s here), after the I2C controller and regulator core are fully up.
>
> On your question of when the device-link error is printed - it is at
> power-domain
> controller probe, not at the rocket probe:
>
> [ 2.700618] vdd_npu: Bringing 500000uV into 825000-825000uV
> [ 2.749637] rockchip-pm-domain fdd90000.power-management:power-controller:
> Failed to create device link (0x180) with supplier 0-0020 for
> /power-management@fdd90000/power-controller/power-domain@6
> [ 2.945955] platform fde40000.npu: Adding to iommu group 3
> ...
> [ 6.840374] rocket: loading out-of-tree module taints kernel.
> [ 6.877647] [drm] Initialized rocket 0.0.0 for rknn on minor 0
> [ 6.879950] rocket fde40000.npu: Rockchip NPU core 0 version: 0
>
> So the device-link to the rk809 PMIC (0-0020) fails to form at ~2.75
> s, well before rocket
> loads at ~6.8 s. It is non-fatal here - the vdd_npu rail is brought up
> by the regulator core
> and all jobs run - and there is no "failed to get ack on domain npu"
> NoC warning this boot
> (the always-on kernel had one). The complete boot log is attached.
>
> Two notes / one question:
> - This boot used fw_devlink=permissive on the command line. Is the
> "Failed to create device
> link ... supplier 0-0020" at pmdomain probe expected/benign, or is
> there a clean way to make
> it order correctly (so it also works without permissive, and a =y
> build wouldn't deadlock in
> the initcalls)?
We encountered the same issue on the RK3588 NPU before. And it was
resolved with the following patch at that time.
https://lore.kernel.org/all/20251216055247.13150-1-rmxpzlb@gmail.com/
Please compare the differences in NPU pmdomain and DTS configuration
between the RK3568 and RK3588.
> - (The convolution output is still uniform zero-point / the job times
> out - that is the
> separate NPU compute-completion issue, unrelated to the power-domain
> work. Finley, that is
> the one I flagged earlier re PVTPLL/NoC.)
>
> Kind regards,
> Midgy
>
--
Best,
Chaoyi
^ permalink raw reply
* Re: [PATCHv2 1/4] serial: mxs-auart: fix cast type for of_device_get_match_data
From: Frank Li @ 2026-06-10 1:13 UTC (permalink / raw)
To: Rosen Penev
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
open list:TTY LAYER AND SERIAL DRIVERS,
open list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20260609223717.41670-2-rosenp@gmail.com>
On Tue, Jun 09, 2026 at 03:37:14PM -0700, Rosen Penev wrote:
> of_device_get_match_data returns const void*. Cast to unsigned long to
> avoid implicit integer truncation warnings. All the data parameters are
> correct anyway.
It is not worth to fix it by this ways. cast void * to int/long is not good
at all.
struct drvdata
{
enum mxs_auart_type type;
}
static const struct drvata chip_imx28;
&chip_imx28 as drv data.
Frank
>
> Assisted-by: opencode:big-pickle
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/tty/serial/mxs-auart.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
> index 697318dbb146..de97c0f74e7d 100644
> --- a/drivers/tty/serial/mxs-auart.c
> +++ b/drivers/tty/serial/mxs-auart.c
> @@ -1598,7 +1598,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
> return -EINVAL;
> }
>
> - s->devtype = (enum mxs_auart_type)of_device_get_match_data(&pdev->dev);
> + s->devtype = (unsigned long)of_device_get_match_data(&pdev->dev);
>
> ret = mxs_get_clks(s, pdev);
> if (ret)
> --
> 2.54.0
>
>
^ permalink raw reply
* [soc:arm/fixes] BUILD SUCCESS 9c648f3554920721d8878807cd794fe2d7f989e8
From: kernel test robot @ 2026-06-10 0:55 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-arm-kernel, arm
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 9c648f3554920721d8878807cd794fe2d7f989e8 Merge tag 'v7.1-rockchip-arm32fixe' of https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into arm/fixes
elapsed time: 1055m
configs tested: 179
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-16.1.0
alpha allyesconfig gcc-16.1.0
alpha defconfig gcc-16.1.0
arc allmodconfig clang-23
arc allnoconfig gcc-16.1.0
arc allyesconfig clang-23
arc axs101_defconfig gcc-16.1.0
arc defconfig gcc-16.1.0
arc randconfig-001-20260610 gcc-8.5.0
arc randconfig-002-20260610 gcc-8.5.0
arm allnoconfig gcc-16.1.0
arm allyesconfig clang-23
arm defconfig gcc-16.1.0
arm randconfig-001-20260610 gcc-8.5.0
arm randconfig-002-20260610 gcc-8.5.0
arm randconfig-003-20260610 gcc-8.5.0
arm randconfig-004-20260610 gcc-8.5.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-16.1.0
arm64 defconfig gcc-16.1.0
arm64 randconfig-001-20260610 gcc-11.5.0
arm64 randconfig-002-20260610 gcc-11.5.0
arm64 randconfig-003-20260610 gcc-11.5.0
arm64 randconfig-004-20260610 gcc-11.5.0
csky allmodconfig gcc-16.1.0
csky allnoconfig gcc-16.1.0
csky defconfig gcc-16.1.0
csky randconfig-001-20260610 gcc-11.5.0
csky randconfig-002-20260610 gcc-11.5.0
hexagon allmodconfig gcc-16.1.0
hexagon allnoconfig gcc-16.1.0
hexagon defconfig gcc-16.1.0
hexagon randconfig-001 gcc-11.5.0
hexagon randconfig-001-20260610 clang-22
hexagon randconfig-001-20260610 gcc-11.5.0
hexagon randconfig-002 gcc-11.5.0
hexagon randconfig-002-20260610 clang-22
hexagon randconfig-002-20260610 gcc-11.5.0
i386 allmodconfig clang-22
i386 allnoconfig gcc-16.1.0
i386 allyesconfig clang-22
i386 buildonly-randconfig-001-20260610 gcc-14
i386 buildonly-randconfig-002-20260610 gcc-14
i386 buildonly-randconfig-003-20260610 gcc-14
i386 buildonly-randconfig-004-20260610 gcc-14
i386 buildonly-randconfig-005-20260610 gcc-14
i386 buildonly-randconfig-006-20260610 gcc-14
i386 defconfig gcc-16.1.0
i386 randconfig-001-20260610 gcc-14
i386 randconfig-002-20260610 gcc-14
i386 randconfig-003-20260610 gcc-14
i386 randconfig-004-20260610 gcc-14
i386 randconfig-005-20260610 gcc-14
i386 randconfig-006-20260610 gcc-14
i386 randconfig-007-20260610 gcc-14
i386 randconfig-011-20260610 gcc-14
i386 randconfig-012-20260610 gcc-14
i386 randconfig-013-20260610 gcc-14
i386 randconfig-014-20260610 gcc-14
i386 randconfig-015-20260610 gcc-14
i386 randconfig-016-20260610 gcc-14
i386 randconfig-017-20260610 gcc-14
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-16.1.0
loongarch randconfig-001 gcc-11.5.0
loongarch randconfig-001-20260610 clang-22
loongarch randconfig-001-20260610 gcc-11.5.0
loongarch randconfig-002 gcc-11.5.0
loongarch randconfig-002-20260610 clang-22
loongarch randconfig-002-20260610 gcc-11.5.0
m68k allmodconfig gcc-16.1.0
m68k allnoconfig gcc-16.1.0
m68k allyesconfig clang-23
microblaze allnoconfig gcc-16.1.0
microblaze allyesconfig gcc-16.1.0
mips allmodconfig gcc-16.1.0
mips allnoconfig gcc-16.1.0
mips allyesconfig gcc-16.1.0
nios2 allmodconfig clang-20
nios2 allnoconfig clang-23
nios2 randconfig-001 gcc-11.5.0
nios2 randconfig-001-20260610 clang-22
nios2 randconfig-001-20260610 gcc-11.5.0
nios2 randconfig-002 gcc-11.5.0
nios2 randconfig-002-20260610 clang-22
nios2 randconfig-002-20260610 gcc-11.5.0
openrisc allmodconfig clang-20
openrisc allnoconfig clang-23
openrisc defconfig gcc-16.1.0
parisc allmodconfig gcc-16.1.0
parisc allnoconfig clang-23
parisc allyesconfig clang-17
parisc allyesconfig clang-23
parisc defconfig gcc-16.1.0
parisc randconfig-001-20260610 gcc-8.5.0
parisc randconfig-002-20260610 gcc-8.5.0
powerpc allmodconfig gcc-16.1.0
powerpc allnoconfig clang-23
powerpc randconfig-001-20260610 gcc-8.5.0
powerpc randconfig-002-20260610 gcc-8.5.0
powerpc64 randconfig-001-20260610 gcc-8.5.0
powerpc64 randconfig-002-20260610 gcc-8.5.0
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allyesconfig clang-23
riscv defconfig gcc-16.1.0
riscv randconfig-001-20260610 gcc-16.1.0
riscv randconfig-002-20260610 gcc-16.1.0
s390 allmodconfig clang-17
s390 allmodconfig clang-23
s390 allnoconfig clang-23
s390 allyesconfig gcc-16.1.0
s390 defconfig gcc-16.1.0
s390 randconfig-001-20260610 gcc-16.1.0
s390 randconfig-002-20260610 gcc-16.1.0
sh allmodconfig gcc-16.1.0
sh allnoconfig clang-23
sh allyesconfig clang-17
sh allyesconfig clang-23
sh defconfig gcc-14
sh randconfig-001-20260610 gcc-16.1.0
sh randconfig-002-20260610 gcc-16.1.0
sparc allnoconfig clang-23
sparc defconfig gcc-16.1.0
sparc randconfig-001-20260610 gcc-14.3.0
sparc randconfig-002-20260610 gcc-14.3.0
sparc64 allmodconfig clang-20
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260610 gcc-14.3.0
sparc64 randconfig-002-20260610 gcc-14.3.0
um allmodconfig clang-17
um allmodconfig clang-23
um allnoconfig clang-23
um allyesconfig gcc-16.1.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260610 gcc-14.3.0
um randconfig-002-20260610 gcc-14.3.0
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-22
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-22
x86_64 buildonly-randconfig-001-20260610 gcc-14
x86_64 buildonly-randconfig-002-20260610 gcc-14
x86_64 buildonly-randconfig-003-20260610 gcc-14
x86_64 buildonly-randconfig-004-20260610 gcc-14
x86_64 buildonly-randconfig-005-20260610 gcc-14
x86_64 buildonly-randconfig-006-20260610 gcc-14
x86_64 defconfig gcc-14
x86_64 kexec clang-22
x86_64 randconfig-001-20260610 gcc-13
x86_64 randconfig-002-20260610 gcc-13
x86_64 randconfig-003-20260610 gcc-13
x86_64 randconfig-004-20260610 gcc-13
x86_64 randconfig-005-20260610 gcc-13
x86_64 randconfig-006-20260610 gcc-13
x86_64 randconfig-011-20260610 gcc-14
x86_64 randconfig-012-20260610 gcc-14
x86_64 randconfig-013-20260610 gcc-14
x86_64 randconfig-014-20260610 gcc-14
x86_64 randconfig-015-20260610 gcc-14
x86_64 randconfig-016-20260610 gcc-14
x86_64 randconfig-071-20260610 gcc-14
x86_64 randconfig-072-20260610 gcc-14
x86_64 randconfig-073-20260610 gcc-14
x86_64 randconfig-074-20260610 gcc-14
x86_64 randconfig-075-20260610 gcc-14
x86_64 randconfig-076-20260610 gcc-14
x86_64 rhel-9.4 clang-22
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-22
x86_64 rhel-9.4-kselftests clang-22
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-22
xtensa allnoconfig clang-23
xtensa allyesconfig clang-20
xtensa randconfig-001-20260610 gcc-14.3.0
xtensa randconfig-002-20260610 gcc-14.3.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox