From c17134d3aea97cd357dd90e3706c61de037dc533 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 19 Oct 2023 22:07:04 +0200 Subject: [PATCH] pwm: stm32: Fix enable count for clk in .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit [ Upstream commit 19f1016ea9600ed89bc24247c36ff5934ad94fbb ] Make the driver take over hardware state without disabling in .probe() and enable the clock for each enabled channel. Signed-off-by: Philipp Zabel [ukleinek: split off from a patch that also implemented .get_state()] Signed-off-by: Uwe Kleine-König Fixes: 7edf7369205b ("pwm: Add driver for STM32 plaftorm") Reviewed-by: Fabrice Gasnier Signed-off-by: Thierry Reding Signed-off-by: Sasha Levin --- drivers/pwm/pwm-stm32.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 0c7781f..dd2ee5d 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -579,17 +579,21 @@ static void stm32_pwm_detect_complementary(struct stm32_pwm *priv) priv->have_complementary_output = (ccer != 0); } -static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv) +static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, + unsigned int *num_enabled) { - u32 ccer; + u32 ccer, ccer_backup; /* * If channels enable bits don't exist writing 1 will have no * effect so we can detect and count them. */ + regmap_read(priv->regmap, TIM_CCER, &ccer_backup); regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); regmap_read(priv->regmap, TIM_CCER, &ccer); - regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); + regmap_write(priv->regmap, TIM_CCER, ccer_backup); + + *num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE); return hweight32(ccer & TIM_CCER_CCXE); } @@ -600,6 +604,8 @@ static int stm32_pwm_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); struct stm32_pwm *priv; + unsigned int num_enabled; + unsigned int i; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -622,7 +628,11 @@ static int stm32_pwm_probe(struct platform_device *pdev) priv->chip.dev = dev; priv->chip.ops = &stm32pwm_ops; - priv->chip.npwm = stm32_pwm_detect_channels(priv); + priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); + + /* Initialize clock refcount to number of enabled PWM channels. */ + for (i = 0; i < num_enabled; i++) + clk_enable(priv->clk); ret = devm_pwmchip_add(dev, &priv->chip); if (ret < 0) -- 2.7.4