From: Xu Rao When lowering the voltage with OVP enabled and a discrete control regulator, vctrl_set_voltage_sel() splits the transition into steps and waits for the output voltage to settle after each step. However, it assigns next_sel to vctrl->sel before calculating the voltage drop. Both voltage table lookups then refer to the same entry, so the calculated delay is always zero. Consecutive downward steps can therefore outpace the output voltage decay and trigger an unwanted OVP shutdown. Calculate the delay before updating vctrl->sel. The voltage difference in microvolts divided by min-slew-down-rate in microvolts per microsecond gives the settling time, as documented in the vctrl regulator binding. This matches the continuous-voltage path and preserves selector tracking for subsequent steps and error recovery. The supplied fix was reviewed and this commit message prepared with OpenCode AI assistance. Fixes: 9dee7a72d0c7 ("regulator: Add driver for voltage controlled regulators") Signed-off-by: Xu Rao Cc: stable@vger.kernel.org --- drivers/regulator/vctrl-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c index 2796580a3a3c..d585eaae0433 100644 --- a/drivers/regulator/vctrl-regulator.c +++ b/drivers/regulator/vctrl-regulator.c @@ -197,11 +197,11 @@ static int vctrl_set_voltage_sel(struct regulator_dev *rdev, vctrl->vtable[next_sel].ctrl); goto err; } - vctrl->sel = next_sel; delay = DIV_ROUND_UP(vctrl->vtable[vctrl->sel].out - vctrl->vtable[next_sel].out, vctrl->min_slew_down_rate); + vctrl->sel = next_sel; usleep_range(delay, delay + DIV_ROUND_UP(delay, 10)); } -- 2.50.1