From 0e1c8dcbdecefea93dee19419b2f67dca591dd42 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 26 Oct 2023 16:48:20 +0200 Subject: [PATCH 1/5] regulator: dt-bindings: Add system-critical-regulator property Introduce a new Device Tree property 'system-critical-regulator' for marking a regulator as crucial for system stability or functionality. This helps in distinguishing regulators that are vital for system operations and may require special handling in under-voltage scenarios. Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Link: https://lore.kernel.org/r/20231026144824.4065145-2-o.rempel@pengutronix.de Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/regulator.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/regulator.yaml b/Documentation/devicetree/bindings/regulator/regulator.yaml index 9daf0fc2465f..5b8d55f7c43b 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/regulator.yaml @@ -114,6 +114,11 @@ properties: description: Enable pull down resistor when the regulator is disabled. type: boolean + system-critical-regulator: + description: Set if the regulator is critical to system stability or + functionality. + type: boolean + regulator-over-current-protection: description: Enable over current protection. type: boolean From 8156c7dd47b92fc4a70c9ea58e7a9e88c8bc32be Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 26 Oct 2023 16:48:21 +0200 Subject: [PATCH 2/5] regulator: Introduce handling for system-critical under-voltage events Handle under-voltage events for crucial regulators to maintain system stability and avoid issues during power drops. Signed-off-by: Oleksij Rempel Link: https://lore.kernel.org/r/20231026144824.4065145-3-o.rempel@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/core.c | 38 +++++++++++++++++++++++++++++++ drivers/regulator/of_regulator.c | 2 ++ include/linux/regulator/machine.h | 10 ++++++++ 3 files changed, 50 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 3137e40fcd3e..a072f721f288 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -5061,6 +5062,41 @@ void regulator_bulk_free(int num_consumers, } EXPORT_SYMBOL_GPL(regulator_bulk_free); +/** + * regulator_handle_critical - Handle events for system-critical regulators. + * @rdev: The regulator device. + * @event: The event being handled. + * + * This function handles critical events such as under-voltage, over-current, + * and unknown errors for regulators deemed system-critical. On detecting such + * events, it triggers a hardware protection shutdown with a defined timeout. + */ +static void regulator_handle_critical(struct regulator_dev *rdev, + unsigned long event) +{ + const char *reason = NULL; + + if (!rdev->constraints->system_critical) + return; + + switch (event) { + case REGULATOR_EVENT_UNDER_VOLTAGE: + reason = "System critical regulator: voltage drop detected"; + break; + case REGULATOR_EVENT_OVER_CURRENT: + reason = "System critical regulator: over-current detected"; + break; + case REGULATOR_EVENT_FAIL: + reason = "System critical regulator: unknown error"; + } + + if (!reason) + return; + + hw_protection_shutdown(reason, + REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS); +} + /** * regulator_notifier_call_chain - call regulator event notifier * @rdev: regulator source @@ -5073,6 +5109,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free); int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data) { + regulator_handle_critical(rdev, event); + _notifier_call_chain(rdev, event, data); return NOTIFY_DONE; diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 1b65e5e4e40f..3bdd6f1919a4 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -131,6 +131,8 @@ static int of_get_regulation_constraints(struct device *dev, constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; constraints->pull_down = of_property_read_bool(np, "regulator-pull-down"); + constraints->system_critical = of_property_read_bool(np, + "system-critical-regulator"); if (of_property_read_bool(np, "regulator-allow-bypass")) constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 621b7f4a3639..e0ddfb5593c9 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -49,6 +49,13 @@ struct regulator; #define DISABLE_IN_SUSPEND 1 #define ENABLE_IN_SUSPEND 2 +/* + * Default time window (in milliseconds) following a critical under-voltage + * event during which less critical actions can be safely carried out by the + * system. + */ +#define REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS 10 + /* Regulator active discharge flags */ enum regulator_active_discharge { REGULATOR_ACTIVE_DISCHARGE_DEFAULT, @@ -127,6 +134,8 @@ struct notification_limit { * @ramp_disable: Disable ramp delay when initialising or when setting voltage. * @soft_start: Enable soft start so that voltage ramps slowly. * @pull_down: Enable pull down when regulator is disabled. + * @system_critical: Set if the regulator is critical to system stability or + * functionality. * @over_current_protection: Auto disable on over current event. * * @over_current_detection: Configure over current limits. @@ -214,6 +223,7 @@ struct regulation_constraints { unsigned ramp_disable:1; /* disable ramp delay */ unsigned soft_start:1; /* ramp voltage slowly */ unsigned pull_down:1; /* pull down resistor when regulator off */ + unsigned system_critical:1; /* critical to system stability */ unsigned over_current_protection:1; /* auto disable on over current */ unsigned over_current_detection:1; /* notify on over current */ unsigned over_voltage_detection:1; /* notify on over voltage */ From 633cd1c0a9de7609f97c0c86e3ac81153e8263b0 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 26 Oct 2023 16:48:22 +0200 Subject: [PATCH 3/5] regulator: dt-bindings: Allow system-critical marking for fixed-regulator In certain projects, the main system regulator, composed of simple components including an under-voltage detector and capacitors, can be aptly described as a fixed regulator in the device tree. To cater to such use cases, this patch extends the fixed regulator binding to support the 'system-critical-regulator' property. This property signifies that the fixed-regulator is vital for system stability. Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Link: https://lore.kernel.org/r/20231026144824.4065145-4-o.rempel@pengutronix.de Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/fixed-regulator.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml index ce7751b9129c..9ff9abf2691a 100644 --- a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml @@ -105,6 +105,8 @@ properties: description: Interrupt signaling a critical under-voltage event. + system-critical-regulator: true + required: - compatible - regulator-name From 759e2bd96971763db1cfaf6cafc07654b12aa21e Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 26 Oct 2023 16:48:23 +0200 Subject: [PATCH 4/5] regulator: dt-bindings: Add 'regulator-uv-less-critical-window-ms' property Introduces a new devicetree property to specifies the time window (in milliseconds) following a critical under-voltage (UV) event during which less critical actions can be safely carried out by the system. Less Critical Actions: - Logging the under-voltage event for later analysis. - Saving less critical data that may be useful for diagnosing issues or for audit purposes. More Critical Actions (post the less critical window): - Initiating procedures to properly shutdown hardware to prevent damage. The 'regulator-uv-less-critical-window-ms' property is crucial for conveying board-specific hardware characteristics, not for enforcing a certain policy. The time window represented by this property is derived from the physical attributes of the hardware like the capacity of on-board capacitors, the power consumption of the components, and the time needed to safely shut down hardware to prevent damage. These attributes can significantly vary between different boards, making it a board-specific property rather than a policy directive. By providing a precise representation of the time available for less critical actions post an under-voltage event, this property enables the kernel to make informed decisions on action prioritization, ensuring that essential preventative measures are taken to avoid hardware damage while also allowing for data capture and analysis. Signed-off-by: Oleksij Rempel Acked-by: Rob Herring Link: https://lore.kernel.org/r/20231026144824.4065145-5-o.rempel@pengutronix.de Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/regulator.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/regulator/regulator.yaml b/Documentation/devicetree/bindings/regulator/regulator.yaml index 5b8d55f7c43b..1ef380d1515e 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/regulator.yaml @@ -186,6 +186,14 @@ properties: be enabled but limit setting can be omitted. Limit is given as microvolt offset from voltage set to regulator. + regulator-uv-less-critical-window-ms: + description: Specifies the time window (in milliseconds) following a + critical under-voltage event during which the system can continue to + operate safely while performing less critical operations. This property + provides a defined duration before a more severe reaction to the + under-voltage event is needed, allowing for certain non-urgent actions to + be carried out in preparation for potential power loss. + regulator-temp-protection-kelvin: description: Set over temperature protection limit. This is a limit where hardware performs emergency shutdown. Zero can be passed to disable From 1e22152aa59d793743fc53051dd7a042f362aecb Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 26 Oct 2023 16:48:24 +0200 Subject: [PATCH 5/5] regulator: Implement uv_survival_time for handling under-voltage events Add 'uv_survival_time' field to regulation_constraints for specifying survival time post critical under-voltage event. Update the regulator notifier call chain and Device Tree property parsing to use this new field, allowing a configurable timeout before emergency shutdown. Signed-off-by: Oleksij Rempel Link: https://lore.kernel.org/r/20231026144824.4065145-6-o.rempel@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- drivers/regulator/of_regulator.c | 7 +++++++ include/linux/regulator/machine.h | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a072f721f288..a6cb84af989e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -5094,7 +5094,7 @@ static void regulator_handle_critical(struct regulator_dev *rdev, return; hw_protection_shutdown(reason, - REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS); + rdev->constraints->uv_less_critical_window_ms); } /** diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 3bdd6f1919a4..03afc160fc72 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -175,6 +175,13 @@ static int of_get_regulation_constraints(struct device *dev, if (!ret) constraints->enable_time = pval; + ret = of_property_read_u32(np, "regulator-uv-survival-time-ms", &pval); + if (!ret) + constraints->uv_less_critical_window_ms = pval; + else + constraints->uv_less_critical_window_ms = + REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS; + constraints->soft_start = of_property_read_bool(np, "regulator-soft-start"); ret = of_property_read_u32(np, "regulator-active-discharge", &pval); diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index e0ddfb5593c9..0cd76d264727 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -162,6 +162,13 @@ struct notification_limit { * regulator_active_discharge values are used for * initialisation. * @enable_time: Turn-on time of the rails (unit: microseconds) + * @uv_less_critical_window_ms: Specifies the time window (in milliseconds) + * following a critical under-voltage (UV) event + * during which less critical actions can be + * safely carried out by the system (for example + * logging). After this time window more critical + * actions should be done (for example prevent + * HW damage). */ struct regulation_constraints { @@ -213,6 +220,7 @@ struct regulation_constraints { unsigned int settling_time_up; unsigned int settling_time_down; unsigned int enable_time; + unsigned int uv_less_critical_window_ms; unsigned int active_discharge;