| From: Ahmad Fatoum <a.fatoum@pengutronix.de> |
| Subject: regulator: allow user configuration of hardware protection action |
| Date: Mon, 17 Feb 2025 21:39:48 +0100 |
| |
| 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> |
| --- |
| |
| drivers/regulator/core.c | 4 ++-- |
| drivers/regulator/irq_helpers.c | 16 ++++++++-------- |
| 2 files changed, 10 insertions(+), 10 deletions(-) |
| |
| --- a/drivers/regulator/core.c~regulator-allow-user-configuration-of-hardware-protection-action |
| +++ a/drivers/regulator/core.c |
| @@ -5262,8 +5262,8 @@ static void regulator_handle_critical(st |
| if (!reason) |
| return; |
| |
| - hw_protection_shutdown(reason, |
| - rdev->constraints->uv_less_critical_window_ms); |
| + hw_protection_trigger(reason, |
| + rdev->constraints->uv_less_critical_window_ms); |
| } |
| |
| /** |
| --- a/drivers/regulator/irq_helpers.c~regulator-allow-user-configuration-of-hardware-protection-action |
| +++ a/drivers/regulator/irq_helpers.c |
| @@ -64,16 +64,16 @@ static void regulator_notifier_isr_work( |
| reread: |
| if (d->fatal_cnt && h->retry_cnt > d->fatal_cnt) { |
| if (!d->die) |
| - return hw_protection_shutdown("Regulator HW failure? - no IC recovery", |
| - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| + return hw_protection_trigger("Regulator HW failure? - no IC recovery", |
| + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| ret = d->die(rid); |
| /* |
| * If the 'last resort' IC recovery failed we will have |
| * nothing else left to do... |
| */ |
| if (ret) |
| - return hw_protection_shutdown("Regulator HW failure. IC recovery failed", |
| - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| + return hw_protection_trigger("Regulator HW failure. IC recovery failed", |
| + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| |
| /* |
| * If h->die() was implemented we assume recovery has been |
| @@ -263,14 +263,14 @@ fail_out: |
| if (d->fatal_cnt && h->retry_cnt > d->fatal_cnt) { |
| /* If we have no recovery, just try shut down straight away */ |
| if (!d->die) { |
| - hw_protection_shutdown("Regulator failure. Retry count exceeded", |
| - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| + hw_protection_trigger("Regulator failure. Retry count exceeded", |
| + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| } else { |
| ret = d->die(rid); |
| /* If die() failed shut down as a last attempt to save the HW */ |
| if (ret) |
| - hw_protection_shutdown("Regulator failure. Recovery failed", |
| - REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| + hw_protection_trigger("Regulator failure. Recovery failed", |
| + REGULATOR_FORCED_SAFETY_SHUTDOWN_WAIT_MS); |
| } |
| } |
| |
| _ |