Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Uwe Kleine-König and committed by
Uwe Kleine-König
a911f157 f43e1280

+47
+47
drivers/pwm/pwm-mediatek.c
··· 232 232 .apply = pwm_mediatek_apply, 233 233 }; 234 234 235 + static int pwm_mediatek_init_used_clks(struct pwm_mediatek_chip *pc) 236 + { 237 + const struct pwm_mediatek_of_data *soc = pc->soc; 238 + unsigned int hwpwm; 239 + u32 enabled, handled = 0; 240 + int ret; 241 + 242 + ret = clk_prepare_enable(pc->clk_top); 243 + if (ret) 244 + return ret; 245 + 246 + ret = clk_prepare_enable(pc->clk_main); 247 + if (ret) 248 + goto err_enable_main; 249 + 250 + enabled = readl(pc->regs) & GENMASK(soc->num_pwms - 1, 0); 251 + 252 + while (enabled & ~handled) { 253 + hwpwm = ilog2(enabled & ~handled); 254 + 255 + ret = pwm_mediatek_clk_enable(pc, hwpwm); 256 + if (ret) { 257 + while (handled) { 258 + hwpwm = ilog2(handled); 259 + 260 + pwm_mediatek_clk_disable(pc, hwpwm); 261 + handled &= ~BIT(hwpwm); 262 + } 263 + 264 + break; 265 + } 266 + 267 + handled |= BIT(hwpwm); 268 + } 269 + 270 + clk_disable_unprepare(pc->clk_main); 271 + err_enable_main: 272 + 273 + clk_disable_unprepare(pc->clk_top); 274 + 275 + return ret; 276 + } 277 + 235 278 static int pwm_mediatek_probe(struct platform_device *pdev) 236 279 { 237 280 struct pwm_chip *chip; ··· 321 278 return dev_err_probe(&pdev->dev, PTR_ERR(pc->clk_pwms[i]), 322 279 "Failed to get %s clock\n", name); 323 280 } 281 + 282 + ret = pwm_mediatek_init_used_clks(pc); 283 + if (ret) 284 + return dev_err_probe(&pdev->dev, ret, "Failed to initialize used clocks\n"); 324 285 325 286 chip->ops = &pwm_mediatek_ops; 326 287