[PATCH V2 1/8] i3c: master: Make hot-join workqueue freezable to block hot-join during suspend
Adrian Hunter
adrian.hunter at intel.com
Mon May 18 04:55:12 PDT 2026
The I3C master workqueue (master->wq) is used to defer work that needs
thread context and the bus maintenance lock, most notably Hot Join
processing (which calls i3c_master_do_daa() to assign dynamic addresses
to newly joined devices).
Currently the workqueue keeps running across system suspend, which can
race with the suspend path:
- do_daa() may execute after the controller has been suspended,
issuing bus transactions on a powered-down or otherwise unusable
controller.
- New I3C devices can be enumerated and added to the bus mid-suspend,
registering driver model objects at a point where the I3C subsystem
and its consumers are not prepared to handle them.
Mark the workqueue WQ_FREEZABLE so its workers are frozen for the
duration of system suspend/hibernate and resumed afterwards. This
naturally defers any pending or newly queued Hot Join work until the
system (and the controller) is fully resumed, closing both races
without adding explicit suspend/resume synchronization in the master
drivers.
Update the kerneldoc for struct i3c_master_controller::wq to reflect
that the workqueue is freezable.
Fixes: 3a379bbcea0af ("i3c: Add core I3C infrastructure")
Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
Reviewed-by: Frank Li <Frank.Li at nxp.com>
---
Changes in V2:
Add Fixes tag
Add Frank's Rev'd by
drivers/i3c/master.c | 2 +-
include/linux/i3c/master.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 5cd4e5da2233..ab11e2d79aab 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -3079,7 +3079,7 @@ int i3c_master_register(struct i3c_master_controller *master,
if (ret)
goto err_put_dev;
- master->wq = alloc_workqueue("%s", WQ_PERCPU, 0, dev_name(parent));
+ master->wq = alloc_workqueue("%s", WQ_PERCPU | WQ_FREEZABLE, 0, dev_name(parent));
if (!master->wq) {
ret = -ENOMEM;
goto err_put_dev;
diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h
index 592b646f6134..e6112e5f6608 100644
--- a/include/linux/i3c/master.h
+++ b/include/linux/i3c/master.h
@@ -515,7 +515,7 @@ struct i3c_master_controller_ops {
* @boardinfo.i2c: list of I2C boardinfo objects
* @boardinfo: board-level information attached to devices connected on the bus
* @bus: I3C bus exposed by this master
- * @wq: workqueue which can be used by master
+ * @wq: freezable workqueue which can be used by master
* drivers if they need to postpone operations that need to take place
* in a thread context. Typical examples are Hot Join processing which
* requires taking the bus lock in maintenance, which in turn, can only
--
2.51.0
More information about the linux-i3c
mailing list