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 <u.kleine-koenig@baylibre.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20250725154506.2610172-14-u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
This commit is contained in:
Uwe Kleine-König 2025-07-25 17:45:08 +02:00 committed by Uwe Kleine-König
parent f43e128073
commit a911f15745

View File

@ -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);