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

regulator: add under-voltage support (part 2)

Merge series from Oleksij Rempel <o.rempel@pengutronix.de>:

This series add under-voltage and emergency shutdown for system critical
regulators

+80
+2
Documentation/devicetree/bindings/regulator/fixed-regulator.yaml
··· 105 105 description: 106 106 Interrupt signaling a critical under-voltage event. 107 107 108 + system-critical-regulator: true 109 + 108 110 required: 109 111 - compatible 110 112 - regulator-name
+13
Documentation/devicetree/bindings/regulator/regulator.yaml
··· 114 114 description: Enable pull down resistor when the regulator is disabled. 115 115 type: boolean 116 116 117 + system-critical-regulator: 118 + description: Set if the regulator is critical to system stability or 119 + functionality. 120 + type: boolean 121 + 117 122 regulator-over-current-protection: 118 123 description: Enable over current protection. 119 124 type: boolean ··· 185 180 to disable detection and value '1' indicates that detection should 186 181 be enabled but limit setting can be omitted. Limit is given as microvolt 187 182 offset from voltage set to regulator. 183 + 184 + regulator-uv-less-critical-window-ms: 185 + description: Specifies the time window (in milliseconds) following a 186 + critical under-voltage event during which the system can continue to 187 + operate safely while performing less critical operations. This property 188 + provides a defined duration before a more severe reaction to the 189 + under-voltage event is needed, allowing for certain non-urgent actions to 190 + be carried out in preparation for potential power loss. 188 191 189 192 regulator-temp-protection-kelvin: 190 193 description: Set over temperature protection limit. This is a limit where
+38
drivers/regulator/core.c
··· 19 19 #include <linux/delay.h> 20 20 #include <linux/gpio/consumer.h> 21 21 #include <linux/of.h> 22 + #include <linux/reboot.h> 22 23 #include <linux/regmap.h> 23 24 #include <linux/regulator/of_regulator.h> 24 25 #include <linux/regulator/consumer.h> ··· 5067 5066 EXPORT_SYMBOL_GPL(regulator_bulk_free); 5068 5067 5069 5068 /** 5069 + * regulator_handle_critical - Handle events for system-critical regulators. 5070 + * @rdev: The regulator device. 5071 + * @event: The event being handled. 5072 + * 5073 + * This function handles critical events such as under-voltage, over-current, 5074 + * and unknown errors for regulators deemed system-critical. On detecting such 5075 + * events, it triggers a hardware protection shutdown with a defined timeout. 5076 + */ 5077 + static void regulator_handle_critical(struct regulator_dev *rdev, 5078 + unsigned long event) 5079 + { 5080 + const char *reason = NULL; 5081 + 5082 + if (!rdev->constraints->system_critical) 5083 + return; 5084 + 5085 + switch (event) { 5086 + case REGULATOR_EVENT_UNDER_VOLTAGE: 5087 + reason = "System critical regulator: voltage drop detected"; 5088 + break; 5089 + case REGULATOR_EVENT_OVER_CURRENT: 5090 + reason = "System critical regulator: over-current detected"; 5091 + break; 5092 + case REGULATOR_EVENT_FAIL: 5093 + reason = "System critical regulator: unknown error"; 5094 + } 5095 + 5096 + if (!reason) 5097 + return; 5098 + 5099 + hw_protection_shutdown(reason, 5100 + rdev->constraints->uv_less_critical_window_ms); 5101 + } 5102 + 5103 + /** 5070 5104 * regulator_notifier_call_chain - call regulator event notifier 5071 5105 * @rdev: regulator source 5072 5106 * @event: notifier block ··· 5113 5077 int regulator_notifier_call_chain(struct regulator_dev *rdev, 5114 5078 unsigned long event, void *data) 5115 5079 { 5080 + regulator_handle_critical(rdev, event); 5081 + 5116 5082 _notifier_call_chain(rdev, event, data); 5117 5083 return NOTIFY_DONE; 5118 5084
+9
drivers/regulator/of_regulator.c
··· 131 131 constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; 132 132 133 133 constraints->pull_down = of_property_read_bool(np, "regulator-pull-down"); 134 + constraints->system_critical = of_property_read_bool(np, 135 + "system-critical-regulator"); 134 136 135 137 if (of_property_read_bool(np, "regulator-allow-bypass")) 136 138 constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; ··· 174 172 ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval); 175 173 if (!ret) 176 174 constraints->enable_time = pval; 175 + 176 + ret = of_property_read_u32(np, "regulator-uv-survival-time-ms", &pval); 177 + if (!ret) 178 + constraints->uv_less_critical_window_ms = pval; 179 + else 180 + constraints->uv_less_critical_window_ms = 181 + REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS; 177 182 178 183 constraints->soft_start = of_property_read_bool(np, 179 184 "regulator-soft-start");
+18
include/linux/regulator/machine.h
··· 49 49 #define DISABLE_IN_SUSPEND 1 50 50 #define ENABLE_IN_SUSPEND 2 51 51 52 + /* 53 + * Default time window (in milliseconds) following a critical under-voltage 54 + * event during which less critical actions can be safely carried out by the 55 + * system. 56 + */ 57 + #define REGULATOR_DEF_UV_LESS_CRITICAL_WINDOW_MS 10 58 + 52 59 /* Regulator active discharge flags */ 53 60 enum regulator_active_discharge { 54 61 REGULATOR_ACTIVE_DISCHARGE_DEFAULT, ··· 134 127 * @ramp_disable: Disable ramp delay when initialising or when setting voltage. 135 128 * @soft_start: Enable soft start so that voltage ramps slowly. 136 129 * @pull_down: Enable pull down when regulator is disabled. 130 + * @system_critical: Set if the regulator is critical to system stability or 131 + * functionality. 137 132 * @over_current_protection: Auto disable on over current event. 138 133 * 139 134 * @over_current_detection: Configure over current limits. ··· 162 153 * regulator_active_discharge values are used for 163 154 * initialisation. 164 155 * @enable_time: Turn-on time of the rails (unit: microseconds) 156 + * @uv_less_critical_window_ms: Specifies the time window (in milliseconds) 157 + * following a critical under-voltage (UV) event 158 + * during which less critical actions can be 159 + * safely carried out by the system (for example 160 + * logging). After this time window more critical 161 + * actions should be done (for example prevent 162 + * HW damage). 165 163 */ 166 164 struct regulation_constraints { 167 165 ··· 220 204 unsigned int settling_time_up; 221 205 unsigned int settling_time_down; 222 206 unsigned int enable_time; 207 + unsigned int uv_less_critical_window_ms; 223 208 224 209 unsigned int active_discharge; 225 210 ··· 231 214 unsigned ramp_disable:1; /* disable ramp delay */ 232 215 unsigned soft_start:1; /* ramp voltage slowly */ 233 216 unsigned pull_down:1; /* pull down resistor when regulator off */ 217 + unsigned system_critical:1; /* critical to system stability */ 234 218 unsigned over_current_protection:1; /* auto disable on over current */ 235 219 unsigned over_current_detection:1; /* notify on over current */ 236 220 unsigned over_voltage_detection:1; /* notify on over voltage */