[PATCH v4 3/4] pwm: meson: use bulk API for per-channel clocks
Xianwei Zhao via B4 Relay
devnull+xianwei.zhao.amlogic.com at kernel.org
Thu Aug 27 01:40:12 PDT 2026
From: Xianwei Zhao <xianwei.zhao at amlogic.com>
The S4 PWM driver currently gets each channel clock individually with
of_clk_get() and uses a custom cleanup action to release the clocks.
Use devm_clk_bulk_get_all() instead to retrieve all per-channel clocks
at once. Verify that the number of clocks matches the number of PWM
channels and assign each clock to its corresponding channel.
This also allows the per-channel clock initialization code to be shared
by Meson PWM variants using one clock per channel.
Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
drivers/pwm/pwm-meson.c | 40 ++++++++++++++++------------------------
1 file changed, 16 insertions(+), 24 deletions(-)
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 22cefc6d5dd0..6f151464d7cc 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -497,33 +497,25 @@ static int meson_pwm_init_channels_meson8b_v2(struct pwm_chip *chip)
return meson_pwm_init_clocks_meson8b(chip, mux_parent_data);
}
-static void meson_pwm_s4_put_clk(void *data)
-{
- struct clk *clk = data;
-
- clk_put(clk);
-}
-
-static int meson_pwm_init_channels_s4(struct pwm_chip *chip)
+static int meson_pwm_init_channels_per_channel_clk(struct pwm_chip *chip)
{
struct device *dev = pwmchip_parent(chip);
- struct device_node *np = dev->of_node;
struct meson_pwm *meson = to_meson_pwm(chip);
- int i, ret;
+ struct clk_bulk_data *clks;
+ unsigned int i;
+ int num;
- for (i = 0; i < chip->npwm; i++) {
- meson->channels[i].clk = of_clk_get(np, i);
- if (IS_ERR(meson->channels[i].clk))
- return dev_err_probe(dev,
- PTR_ERR(meson->channels[i].clk),
- "Failed to get clk\n");
-
- ret = devm_add_action_or_reset(dev, meson_pwm_s4_put_clk,
- meson->channels[i].clk);
- if (ret)
- return dev_err_probe(dev, ret,
- "Failed to add clk_put action\n");
- }
+ num = devm_clk_bulk_get_all(dev, &clks);
+ if (num < 0)
+ return dev_err_probe(dev, num, "Failed to get clocks\n");
+
+ if (num != chip->npwm)
+ return dev_err_probe(dev, -EINVAL,
+ "expected %u clocks, got %d\n",
+ chip->npwm, num);
+
+ for (i = 0; i < chip->npwm; i++)
+ meson->channels[i].clk = clks[i].clk;
return 0;
}
@@ -597,7 +589,7 @@ static const struct meson_pwm_data pwm_meson_axg_v2_data = {
};
static const struct meson_pwm_data pwm_s4_data = {
- .channels_init = meson_pwm_init_channels_s4,
+ .channels_init = meson_pwm_init_channels_per_channel_clk,
.has_constant = true,
.has_polarity = true,
.npwm = 2,
--
2.52.0
More information about the linux-amlogic
mailing list