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

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>

authored by

Uwe Kleine-König and committed by
Stephen Boyd
f5f792f0 91d10161

+29 -1
+29 -1
drivers/clk/clk-pwm.c
··· 23 23 return container_of(hw, struct clk_pwm, hw); 24 24 } 25 25 26 + static int clk_pwm_enable(struct clk_hw *hw) 27 + { 28 + struct clk_pwm *clk_pwm = to_clk_pwm(hw); 29 + 30 + return pwm_apply_atomic(clk_pwm->pwm, &clk_pwm->state); 31 + } 32 + 33 + static void clk_pwm_disable(struct clk_hw *hw) 34 + { 35 + struct clk_pwm *clk_pwm = to_clk_pwm(hw); 36 + struct pwm_state state = clk_pwm->state; 37 + 38 + state.enabled = false; 39 + 40 + pwm_apply_atomic(clk_pwm->pwm, &state); 41 + } 42 + 26 43 static int clk_pwm_prepare(struct clk_hw *hw) 27 44 { 28 45 struct clk_pwm *clk_pwm = to_clk_pwm(hw); ··· 77 60 78 61 return 0; 79 62 } 63 + 64 + static const struct clk_ops clk_pwm_ops_atomic = { 65 + .enable = clk_pwm_enable, 66 + .disable = clk_pwm_disable, 67 + .recalc_rate = clk_pwm_recalc_rate, 68 + .get_duty_cycle = clk_pwm_get_duty_cycle, 69 + }; 80 70 81 71 static const struct clk_ops clk_pwm_ops = { 82 72 .prepare = clk_pwm_prepare, ··· 139 115 of_property_read_string(node, "clock-output-names", &clk_name); 140 116 141 117 init.name = clk_name; 142 - init.ops = &clk_pwm_ops; 118 + if (pwm_might_sleep(pwm)) 119 + init.ops = &clk_pwm_ops; 120 + else 121 + init.ops = &clk_pwm_ops_atomic; 122 + 143 123 init.flags = 0; 144 124 init.num_parents = 0; 145 125