Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: allow user configuration of hardware protection action

When the core detects permanent regulator hardware failure or imminent
power failure of a critical supply, it will call hw_protection_shutdown in
an attempt to do a limited orderly shutdown followed by powering off the
system.

This doesn't work out well for many unattended embedded systems that don't
have support for shutdown and that power on automatically when power is
supplied:

- A brief power cycle gets detected by the driver
- The kernel powers down the system and SoC goes into shutdown mode
- Power is restored
- The system remains oblivious to the restored power
- System needs to be manually power cycled for a duration long enough
to drain the capacitors

Allow users to fix this by calling the newly introduced
hw_protection_trigger() instead: This way the hw_protection commandline or
sysfs parameter is used to dictate the policy of dealing with the
regulator fault.

Link: https://lkml.kernel.org/r/20250217-hw_protection-reboot-v3-8-e1c09b090c0c@pengutronix.de
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Reviewed-by: Tzung-Bi Shih <tzungbi@kernel.org>
Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
Cc: Benson Leung <bleung@chromium.org>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Fabio Estevam <festevam@denx.de>
Cc: Guenter Roeck <groeck@chromium.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Lukasz Luba <lukasz.luba@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Matteo Croce <teknoraver@meta.com>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Rob Herring (Arm) <robh@kernel.org>
Cc: Rui Zhang <rui.zhang@intel.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Ahmad Fatoum and committed by
Andrew Morton
b15388a2 e016173f

+10 -10
+2 -2
drivers/regulator/core.c
··· 5262 5262 if (!reason) 5263 5263 return; 5264 5264 5265 - hw_protection_shutdown(reason, 5266 - rdev->constraints->uv_less_critical_window_ms); 5265 + hw_protection_trigger(reason, 5266 + rdev->constraints->uv_less_critical_window_ms); 5267 5267 } 5268 5268 5269 5269 /**
+8 -8
drivers/regulator/irq_helpers.c
··· 64 64 reread: 65 65 if (d->fatal_cnt && h->retry_cnt > d->fatal_cnt) { 66 66 if (!d->die) 67 - return hw_protection_shutdown("Regulator HW failure? - no IC recovery", 68 - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 67 + return hw_protection_trigger("Regulator HW failure? - no IC recovery", 68 + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 69 69 ret = d->die(rid); 70 70 /* 71 71 * If the 'last resort' IC recovery failed we will have 72 72 * nothing else left to do... 73 73 */ 74 74 if (ret) 75 - return hw_protection_shutdown("Regulator HW failure. IC recovery failed", 76 - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 75 + return hw_protection_trigger("Regulator HW failure. IC recovery failed", 76 + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 77 77 78 78 /* 79 79 * If h->die() was implemented we assume recovery has been ··· 263 263 if (d->fatal_cnt && h->retry_cnt > d->fatal_cnt) { 264 264 /* If we have no recovery, just try shut down straight away */ 265 265 if (!d->die) { 266 - hw_protection_shutdown("Regulator failure. Retry count exceeded", 267 - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 266 + hw_protection_trigger("Regulator failure. Retry count exceeded", 267 + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 268 268 } else { 269 269 ret = d->die(rid); 270 270 /* If die() failed shut down as a last attempt to save the HW */ 271 271 if (ret) 272 - hw_protection_shutdown("Regulator failure. Recovery failed", 273 - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 272 + hw_protection_trigger("Regulator failure. Recovery failed", 273 + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); 274 274 } 275 275 } 276 276