summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoy Zou <joy.zou@oss.nxp.com>2026-07-31 18:21:43 +0800
committerMark Brown <broonie@kernel.org>2026-07-31 17:15:14 +0100
commit03eab318cedd6ae34ecd34533cd986edf5237164 (patch)
treeec497ff0f93ad395ba8abe9202e4d852a02a5858
parentf5098b6bae761e346ebcd9da7f95622c04733cff (diff)
downloadlinux-next-03eab318cedd6ae34ecd34533cd986edf5237164.tar.gz
linux-next-03eab318cedd6ae34ecd34533cd986edf5237164.zip
regulator: core: use system_freezable_wq for init complete work
schedule_delayed_work() uses system_wq, which is non-freezable, allowing regulator_init_complete_work to run concurrently with system suspend. This work fires ~30s after boot to disable unused regulators via I2C. When it races with PM suspend, the I2C adapter may already be suspended, triggering a -ESHUTDOWN warning in __i2c_transfer(): WARNING: ... at __i2c_transfer+0x36c/0x3c8 Call trace: __i2c_transfer i2c_transfer regmap_i2c_write _regmap_update_bits regulator_disable_regmap _regulator_do_disable regulator_late_cleanup regulator_init_complete_work_function process_one_work Switch to system_freezable_wq so the work is frozen before any device is suspended, eliminating the race. Fixes: 55576cf18537 ("regulator: Defer init completion for a while after late_initcall") Signed-off-by: Joy Zou <joy.zou@oss.nxp.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20260731-b4-regulator-pf01-v2-1-a406c8737fdb@oss.nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/core.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2e61606fc1d0..6a4008f387b5 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -27,6 +27,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/module.h>
+#include <linux/workqueue.h>
#define CREATE_TRACE_POINTS
#include <trace/events/regulator.h>
@@ -6899,8 +6900,9 @@ static int __init regulator_init_complete(void)
* we'd only do this on systems that need it, and a kernel
* command line option might be useful.
*/
- schedule_delayed_work(&regulator_init_complete_work,
- msecs_to_jiffies(30000));
+ queue_delayed_work(system_freezable_wq,
+ &regulator_init_complete_work,
+ msecs_to_jiffies(30000));
return 0;
}