[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20251011073057.2959-2-guojinhui.liam@bytedance.com>
Date: Sat, 11 Oct 2025 15:30:57 +0800
From: Jinhui Guo <guojinhui.liam@...edance.com>
To: mika.westerberg@...ux.intel.com,
andriy.shevchenko@...ux.intel.com,
jsd@...ihalf.com,
andi.shyti@...nel.org
Cc: guojinhui.liam@...edance.com,
linux-i2c@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 1/1] i2c: designware: Disable SMBus interrupts to prevent storms from mis-configured firmware
When probing the I2C master, disable SMBus interrupts to prevent
storms caused by broken firmware mis-configuring IC_SMBUS=1; the
handler never services them and a mis-configured SMBUS Master
extend-clock timeout can flood the CPU.
Signed-off-by: Jinhui Guo <guojinhui.liam@...edance.com>
---
drivers/i2c/busses/i2c-designware-core.h | 1 +
drivers/i2c/busses/i2c-designware-master.c | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 347843b4f5dd..d1122ff0a1b7 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -78,6 +78,7 @@
#define DW_IC_TX_ABRT_SOURCE 0x80
#define DW_IC_ENABLE_STATUS 0x9c
#define DW_IC_CLR_RESTART_DET 0xa8
+#define DW_IC_SMBUS_INTR_MASK 0xcc
#define DW_IC_COMP_PARAM_1 0xf4
#define DW_IC_COMP_VERSION 0xf8
#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index c7a72c28786c..eeb60536da32 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -997,6 +997,11 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev)
return 0;
}
+static inline void i2c_dw_disable_smbus_intr(struct dw_i2c_dev *dev)
+{
+ regmap_write(dev->map, DW_IC_SMBUS_INTR_MASK, 0);
+}
+
int i2c_dw_probe_master(struct dw_i2c_dev *dev)
{
struct i2c_adapter *adap = &dev->adapter;
@@ -1063,6 +1068,12 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev)
return ret;
__i2c_dw_write_intr_mask(dev, 0);
+ /*
+ * Mask SMBus interrupts to block storms from broken
+ * firmware that leaves IC_SMBUS=1; the handler never
+ * services them.
+ */
+ i2c_dw_disable_smbus_intr(dev);
i2c_dw_release_lock(dev);
if (!(dev->flags & ACCESS_POLLING)) {
--
2.20.1
Powered by blists - more mailing lists