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

pwm: vt8500: Implement .apply() callback

To eventually get rid of all legacy drivers convert this driver to the
modern world implementing .apply(). This just pushes down a slightly
optimized variant of how legacy drivers are handled in the core.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>

authored by

Uwe Kleine-König and committed by
Thierry Reding
14d89565 0ee11b87

+50 -7
+50 -7
drivers/pwm/pwm-vt8500.c
··· 70 70 } 71 71 72 72 static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 73 - int duty_ns, int period_ns) 73 + u64 duty_ns, u64 period_ns) 74 74 { 75 75 struct vt8500_chip *vt8500 = to_vt8500_chip(chip); 76 76 unsigned long long c; ··· 102 102 } 103 103 104 104 c = (unsigned long long)pv * duty_ns; 105 - do_div(c, period_ns); 106 - dc = c; 105 + 106 + dc = div64_u64(c, period_ns); 107 107 108 108 writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm)); 109 109 vt8500_pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE); ··· 176 176 return 0; 177 177 } 178 178 179 + static int vt8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 180 + const struct pwm_state *state) 181 + { 182 + int err; 183 + bool enabled = pwm->state.enabled; 184 + 185 + if (state->polarity != pwm->state.polarity) { 186 + /* 187 + * Changing the polarity of a running PWM is only allowed when 188 + * the PWM driver implements ->apply(). 189 + */ 190 + if (enabled) { 191 + vt8500_pwm_disable(chip, pwm); 192 + 193 + enabled = false; 194 + } 195 + 196 + err = vt8500_pwm_set_polarity(chip, pwm, state->polarity); 197 + if (err) 198 + return err; 199 + } 200 + 201 + if (!state->enabled) { 202 + if (enabled) 203 + vt8500_pwm_disable(chip, pwm); 204 + 205 + return 0; 206 + } 207 + 208 + /* 209 + * We cannot skip calling ->config even if state->period == 210 + * pwm->state.period && state->duty_cycle == pwm->state.duty_cycle 211 + * because we might have exited early in the last call to 212 + * pwm_apply_state because of !state->enabled and so the two values in 213 + * pwm->state might not be configured in hardware. 214 + */ 215 + err = vt8500_pwm_config(pwm->chip, pwm, state->duty_cycle, state->period); 216 + if (err) 217 + return err; 218 + 219 + if (!enabled) 220 + err = vt8500_pwm_enable(chip, pwm); 221 + 222 + return err; 223 + } 224 + 179 225 static const struct pwm_ops vt8500_pwm_ops = { 180 - .enable = vt8500_pwm_enable, 181 - .disable = vt8500_pwm_disable, 182 - .config = vt8500_pwm_config, 183 - .set_polarity = vt8500_pwm_set_polarity, 226 + .apply = vt8500_pwm_apply, 184 227 .owner = THIS_MODULE, 185 228 }; 186 229