On failure inside q6v5_regulator_enable()'s enable loop, the err:
label's unwind loop starts from the same index i that just failed,
calling regulator_disable() on a regulator that was never
successfully enabled by this call (and may not even have reached
regulator_enable() if the failure was in regulator_set_voltage() or
regulator_set_load()). This can trip the regulator core's unbalanced
disable warning, or spuriously drop another consumer's vote on a
shared rail.

Fix this by decrementing i before the unwind loop, so it only
disables regulators that were actually enabled. The current index i
may still have a voltage or load constraint applied from before the
failure, so clear that explicitly ahead of the loop rather than
dropping it along with the erroneous disable() call.

Signed-off-by: Anup Vishwakarma <[email protected]>
---
 drivers/remoteproc/qcom_q6v5_mss.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/qcom_q6v5_mss.c 
b/drivers/remoteproc/qcom_q6v5_mss.c
index 2f71ed2feff6..a40a8614758e 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -336,7 +336,13 @@ static int q6v5_regulator_enable(struct q6v5 *qproc,
 
        return 0;
 err:
-       for (; i >= 0; i--) {
+       if (regs[i].uV > 0)
+               regulator_set_voltage(regs[i].reg, 0, INT_MAX);
+
+       if (regs[i].uA > 0)
+               regulator_set_load(regs[i].reg, 0);
+
+       for (i--; i >= 0; i--) {
                if (regs[i].uV > 0)
                        regulator_set_voltage(regs[i].reg, 0, INT_MAX);
 

---
base-commit: e6e35979777d646fe3c7c94dca7dd32fb25d45f4
change-id: 20260916-b4-q6v5_mss_regulator_enable_unwind_upstream-c613d3b42cef

Best regards,
--  
Anup Vishwakarma <[email protected]>


Reply via email to