[PATCH] pwm: atmel-hlcdc: fix missing clk_disable_unprepare on error paths

Haotian Zhang vulab at iscas.ac.cn
Sun Sep 28 20:19:08 PDT 2025


atmel_hlcdc_pwm_apply() enables a new clock before updating register
settings. If any of the subsequent regmap operations fail, the clock
was left prepared and enabled.

Add a common error path to disable the newly enabled clock.

Fixes: a56960e8b406 ("[media] cec: add HDMI CEC framework (core)")
Signed-off-by: Haotian Zhang <vulab at iscas.ac.cn>
---
 drivers/pwm/pwm-atmel-hlcdc.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/pwm/pwm-atmel-hlcdc.c b/drivers/pwm/pwm-atmel-hlcdc.c
index 387a0d1fa4f2..0791a97c2fb4 100644
--- a/drivers/pwm/pwm-atmel-hlcdc.c
+++ b/drivers/pwm/pwm-atmel-hlcdc.c
@@ -98,9 +98,6 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			if (ret)
 				return ret;
 
-			clk_disable_unprepare(atmel->cur_clk);
-			atmel->cur_clk = new_clk;
-
 			if (new_clk == hlcdc->sys_clk)
 				gencfg = ATMEL_HLCDC_CLKPWMSEL;
 
@@ -109,7 +106,9 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 						 ATMEL_HLCDC_CLKPWMSEL,
 						 gencfg);
 			if (ret)
-				return ret;
+				goto err_disable_clk;
+			clk_disable_unprepare(atmel->cur_clk);
+			atmel->cur_clk = new_clk;
 		}
 
 		do_div(pwmcval, state->period);
@@ -134,19 +133,19 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 					 ATMEL_HLCDC_PWMPOL,
 					 pwmcfg);
 		if (ret)
-			return ret;
+			goto err_disable_clk;
 
 		ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_EN,
 				   ATMEL_HLCDC_PWM);
 		if (ret)
-			return ret;
+			goto err_disable_clk;
 
 		ret = regmap_read_poll_timeout(hlcdc->regmap, ATMEL_HLCDC_SR,
 					       status,
 					       status & ATMEL_HLCDC_PWM,
 					       10, 0);
 		if (ret)
-			return ret;
+			goto err_disable_clk;
 	} else {
 		ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_DIS,
 				   ATMEL_HLCDC_PWM);
@@ -165,6 +164,10 @@ static int atmel_hlcdc_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	return 0;
+
+err_disable_clk:
+	clk_disable_unprepare(new_clk);
+	return ret;
 }
 
 static const struct pwm_ops atmel_hlcdc_pwm_ops = {
-- 
2.50.1.windows.1




More information about the linux-arm-kernel mailing list