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

pwm: imx27: Use clk_bulk_*() API to simplify clock handling

Simplify the clock handling logic by using the clk_bulk_*() API.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240910-pwm-v3-2-fbb047896618@nxp.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>

authored by

Frank Li and committed by
Uwe Kleine-König
f8e87e14 a25351e4

+22 -41
+22 -41
drivers/pwm/pwm-imx27.c
··· 80 80 /* PWMPR register value of 0xffff has the same effect as 0xfffe */ 81 81 #define MX3_PWMPR_MAX 0xfffe 82 82 83 + static const char * const pwm_imx27_clks[] = {"ipg", "per"}; 84 + #define PWM_IMX27_PER 1 85 + 83 86 struct pwm_imx27_chip { 84 - struct clk *clk_ipg; 85 - struct clk *clk_per; 87 + struct clk_bulk_data clks[ARRAY_SIZE(pwm_imx27_clks)]; 88 + int clks_cnt; 86 89 void __iomem *mmio_base; 87 90 88 91 /* ··· 101 98 return pwmchip_get_drvdata(chip); 102 99 } 103 100 104 - static int pwm_imx27_clk_prepare_enable(struct pwm_imx27_chip *imx) 105 - { 106 - int ret; 107 - 108 - ret = clk_prepare_enable(imx->clk_ipg); 109 - if (ret) 110 - return ret; 111 - 112 - ret = clk_prepare_enable(imx->clk_per); 113 - if (ret) { 114 - clk_disable_unprepare(imx->clk_ipg); 115 - return ret; 116 - } 117 - 118 - return 0; 119 - } 120 - 121 - static void pwm_imx27_clk_disable_unprepare(struct pwm_imx27_chip *imx) 122 - { 123 - clk_disable_unprepare(imx->clk_per); 124 - clk_disable_unprepare(imx->clk_ipg); 125 - } 126 - 127 101 static int pwm_imx27_get_state(struct pwm_chip *chip, 128 102 struct pwm_device *pwm, struct pwm_state *state) 129 103 { ··· 109 129 u64 tmp; 110 130 int ret; 111 131 112 - ret = pwm_imx27_clk_prepare_enable(imx); 132 + ret = clk_bulk_prepare_enable(imx->clks_cnt, imx->clks); 113 133 if (ret < 0) 114 134 return ret; 115 135 ··· 132 152 } 133 153 134 154 prescaler = MX3_PWMCR_PRESCALER_GET(val); 135 - pwm_clk = clk_get_rate(imx->clk_per); 155 + pwm_clk = clk_get_rate(imx->clks[PWM_IMX27_PER].clk); 136 156 val = readl(imx->mmio_base + MX3_PWMPR); 137 157 period = val >= MX3_PWMPR_MAX ? MX3_PWMPR_MAX : val; 138 158 ··· 152 172 tmp = NSEC_PER_SEC * (u64)(val) * prescaler; 153 173 state->duty_cycle = DIV_ROUND_UP_ULL(tmp, pwm_clk); 154 174 155 - pwm_imx27_clk_disable_unprepare(imx); 175 + clk_bulk_disable_unprepare(imx->clks_cnt, imx->clks); 156 176 157 177 return 0; 158 178 } ··· 209 229 int ret; 210 230 u32 cr; 211 231 212 - clkrate = clk_get_rate(imx->clk_per); 232 + clkrate = clk_get_rate(imx->clks[PWM_IMX27_PER].clk); 213 233 c = clkrate * state->period; 214 234 215 235 do_div(c, NSEC_PER_SEC); ··· 239 259 if (pwm->state.enabled) { 240 260 pwm_imx27_wait_fifo_slot(chip, pwm); 241 261 } else { 242 - ret = pwm_imx27_clk_prepare_enable(imx); 262 + ret = clk_bulk_prepare_enable(imx->clks_cnt, imx->clks); 243 263 if (ret) 244 264 return ret; 245 265 ··· 361 381 writel(cr, imx->mmio_base + MX3_PWMCR); 362 382 363 383 if (!state->enabled) 364 - pwm_imx27_clk_disable_unprepare(imx); 384 + clk_bulk_disable_unprepare(imx->clks_cnt, imx->clks); 365 385 366 386 return 0; 367 387 } ··· 383 403 struct pwm_imx27_chip *imx; 384 404 int ret; 385 405 u32 pwmcr; 406 + int i; 386 407 387 408 chip = devm_pwmchip_alloc(&pdev->dev, 1, sizeof(*imx)); 388 409 if (IS_ERR(chip)) 389 410 return PTR_ERR(chip); 390 411 imx = to_pwm_imx27_chip(chip); 391 412 392 - imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); 393 - if (IS_ERR(imx->clk_ipg)) 394 - return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_ipg), 395 - "getting ipg clock failed\n"); 413 + imx->clks_cnt = ARRAY_SIZE(pwm_imx27_clks); 414 + for (i = 0; i < imx->clks_cnt; ++i) 415 + imx->clks[i].id = pwm_imx27_clks[i]; 396 416 397 - imx->clk_per = devm_clk_get(&pdev->dev, "per"); 398 - if (IS_ERR(imx->clk_per)) 399 - return dev_err_probe(&pdev->dev, PTR_ERR(imx->clk_per), 400 - "failed to get peripheral clock\n"); 417 + ret = devm_clk_bulk_get(&pdev->dev, imx->clks_cnt, imx->clks); 418 + 419 + if (ret) 420 + return dev_err_probe(&pdev->dev, ret, 421 + "getting clocks failed\n"); 401 422 402 423 chip->ops = &pwm_imx27_ops; 403 424 ··· 406 425 if (IS_ERR(imx->mmio_base)) 407 426 return PTR_ERR(imx->mmio_base); 408 427 409 - ret = pwm_imx27_clk_prepare_enable(imx); 428 + ret = clk_bulk_prepare_enable(imx->clks_cnt, imx->clks); 410 429 if (ret) 411 430 return ret; 412 431 413 432 /* keep clks on if pwm is running */ 414 433 pwmcr = readl(imx->mmio_base + MX3_PWMCR); 415 434 if (!(pwmcr & MX3_PWMCR_EN)) 416 - pwm_imx27_clk_disable_unprepare(imx); 435 + clk_bulk_disable_unprepare(imx->clks_cnt, imx->clks); 417 436 418 437 return devm_pwmchip_add(&pdev->dev, chip); 419 438 }