diff options
| author | Joy Zou <joy.zou@oss.nxp.com> | 2026-07-31 18:21:43 +0800 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-31 17:15:14 +0100 |
| commit | 03eab318cedd6ae34ecd34533cd986edf5237164 (patch) | |
| tree | ec497ff0f93ad395ba8abe9202e4d852a02a5858 | |
| parent | f5098b6bae761e346ebcd9da7f95622c04733cff (diff) | |
| download | linux-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.c | 6 |
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(®ulator_init_complete_work, - msecs_to_jiffies(30000)); + queue_delayed_work(system_freezable_wq, + ®ulator_init_complete_work, + msecs_to_jiffies(30000)); return 0; } |
