From: Uwe Kleine-König Date: Fri, 25 Jul 2025 15:45:08 +0000 (+0200) Subject: pwm: mediatek: Initialize clks when the hardware is enabled at probe time X-Git-Tag: v6.18-rc1~169^2~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a911f15745fd4a93381b52acea3083e7e9fd135a;p=thirdparty%2Fkernel%2Flinux.git pwm: mediatek: Initialize clks when the hardware is enabled at probe time When a PWM is already configured by the bootloader (e.g. to power a backlight), the clk enable count must be increased to keep clock usage balanced. So check which PWMs are enabled during probe and enable the respective clocks. Signed-off-by: Uwe Kleine-König Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20250725154506.2610172-14-u.kleine-koenig@baylibre.com Signed-off-by: Uwe Kleine-König --- diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c index 7fe003bcc74d7..faa0205d4a0dc 100644 --- a/drivers/pwm/pwm-mediatek.c +++ b/drivers/pwm/pwm-mediatek.c @@ -232,6 +232,49 @@ static const struct pwm_ops pwm_mediatek_ops = { .apply = pwm_mediatek_apply, }; +static int pwm_mediatek_init_used_clks(struct pwm_mediatek_chip *pc) +{ + const struct pwm_mediatek_of_data *soc = pc->soc; + unsigned int hwpwm; + u32 enabled, handled = 0; + int ret; + + ret = clk_prepare_enable(pc->clk_top); + if (ret) + return ret; + + ret = clk_prepare_enable(pc->clk_main); + if (ret) + goto err_enable_main; + + enabled = readl(pc->regs) & GENMASK(soc->num_pwms - 1, 0); + + while (enabled & ~handled) { + hwpwm = ilog2(enabled & ~handled); + + ret = pwm_mediatek_clk_enable(pc, hwpwm); + if (ret) { + while (handled) { + hwpwm = ilog2(handled); + + pwm_mediatek_clk_disable(pc, hwpwm); + handled &= ~BIT(hwpwm); + } + + break; + } + + handled |= BIT(hwpwm); + } + + clk_disable_unprepare(pc->clk_main); +err_enable_main: + + clk_disable_unprepare(pc->clk_top); + + return ret; +} + static int pwm_mediatek_probe(struct platform_device *pdev) { struct pwm_chip *chip; @@ -279,6 +322,10 @@ static int pwm_mediatek_probe(struct platform_device *pdev) "Failed to get %s clock\n", name); } + ret = pwm_mediatek_init_used_clks(pc); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed to initialize used clocks\n"); + chip->ops = &pwm_mediatek_ops; ret = devm_pwmchip_add(&pdev->dev, chip);