aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@baylibre.com>2025-04-30 11:57:49 +0200
committerStephen Boyd <sboyd@kernel.org>2025-06-19 18:09:58 -0700
commitf5f792f07bd23f26fcc98a0fca596a2101a6f640 (patch)
tree33d8272f2f4730c20564ce6db5a4e01e016356b0
parentclk: pwm: Don't reconfigure running PWM at probe time (diff)
downloadwireguard-linux-f5f792f07bd23f26fcc98a0fca596a2101a6f640.tar.xz
wireguard-linux-f5f792f07bd23f26fcc98a0fca596a2101a6f640.zip
clk: pwm: Make use of non-sleeping PWMs
For some PWMs applying a configuration doesn't sleep. For these enabling and disabling can be done in the clk callbacks .enable() and .disable() instead of .prepare() and .unprepare(). Do that to possibly reduce the time the PWM is enabled and so save some energy. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Link: https://lore.kernel.org/r/d2f748101194409fb410711380ea52ed33260644.1746006578.git.ukleinek@baylibre.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r--drivers/clk/clk-pwm.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c
index 856828d5f58c..4709f0338e37 100644
--- a/drivers/clk/clk-pwm.c
+++ b/drivers/clk/clk-pwm.c
@@ -23,6 +23,23 @@ static inline struct clk_pwm *to_clk_pwm(struct clk_hw *hw)
return container_of(hw, struct clk_pwm, hw);
}
+static int clk_pwm_enable(struct clk_hw *hw)
+{
+ struct clk_pwm *clk_pwm = to_clk_pwm(hw);
+
+ return pwm_apply_atomic(clk_pwm->pwm, &clk_pwm->state);
+}
+
+static void clk_pwm_disable(struct clk_hw *hw)
+{
+ struct clk_pwm *clk_pwm = to_clk_pwm(hw);
+ struct pwm_state state = clk_pwm->state;
+
+ state.enabled = false;
+
+ pwm_apply_atomic(clk_pwm->pwm, &state);
+}
+
static int clk_pwm_prepare(struct clk_hw *hw)
{
struct clk_pwm *clk_pwm = to_clk_pwm(hw);
@@ -61,6 +78,13 @@ static int clk_pwm_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
return 0;
}
+static const struct clk_ops clk_pwm_ops_atomic = {
+ .enable = clk_pwm_enable,
+ .disable = clk_pwm_disable,
+ .recalc_rate = clk_pwm_recalc_rate,
+ .get_duty_cycle = clk_pwm_get_duty_cycle,
+};
+
static const struct clk_ops clk_pwm_ops = {
.prepare = clk_pwm_prepare,
.unprepare = clk_pwm_unprepare,
@@ -115,7 +139,11 @@ static int clk_pwm_probe(struct platform_device *pdev)
of_property_read_string(node, "clock-output-names", &clk_name);
init.name = clk_name;
- init.ops = &clk_pwm_ops;
+ if (pwm_might_sleep(pwm))
+ init.ops = &clk_pwm_ops;
+ else
+ init.ops = &clk_pwm_ops_atomic;
+
init.flags = 0;
init.num_parents = 0;