in core.c [556:649]
int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
{
struct pwm_chip *chip;
int err;
/*
* Some lowlevel driver's implementations of .apply() make use of
* mutexes, also with some drivers only returning when the new
* configuration is active calling pwm_apply_state() from atomic context
* is a bad idea. So make it explicit that calling this function might
* sleep.
*/
might_sleep();
if (!pwm || !state || !state->period ||
state->duty_cycle > state->period)
return -EINVAL;
chip = pwm->chip;
if (state->period == pwm->state.period &&
state->duty_cycle == pwm->state.duty_cycle &&
state->polarity == pwm->state.polarity &&
state->enabled == pwm->state.enabled &&
state->usage_power == pwm->state.usage_power)
return 0;
if (chip->ops->apply) {
err = chip->ops->apply(chip, pwm, state);
if (err)
return err;
trace_pwm_apply(pwm, state);
pwm->state = *state;
/*
* only do this after pwm->state was applied as some
* implementations of .get_state depend on this
*/
pwm_apply_state_debug(pwm, state);
} else {
/*
* FIXME: restore the initial state in case of error.
*/
if (state->polarity != pwm->state.polarity) {
if (!chip->ops->set_polarity)
return -EINVAL;
/*
* Changing the polarity of a running PWM is
* only allowed when the PWM driver implements
* ->apply().
*/
if (pwm->state.enabled) {
chip->ops->disable(chip, pwm);
pwm->state.enabled = false;
}
err = chip->ops->set_polarity(chip, pwm,
state->polarity);
if (err)
return err;
pwm->state.polarity = state->polarity;
}
if (state->period != pwm->state.period ||
state->duty_cycle != pwm->state.duty_cycle) {
err = chip->ops->config(pwm->chip, pwm,
state->duty_cycle,
state->period);
if (err)
return err;
pwm->state.duty_cycle = state->duty_cycle;
pwm->state.period = state->period;
}
if (state->enabled != pwm->state.enabled) {
if (state->enabled) {
err = chip->ops->enable(chip, pwm);
if (err)
return err;
} else {
chip->ops->disable(chip, pwm);
}
pwm->state.enabled = state->enabled;
}
}
return 0;
}