summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2021-07-01 09:29:27 +0200
committerThierry Reding <thierry.reding@gmail.com>2021-11-17 17:10:42 +0100
commite45a178e9e285c86265611a56705a1e6444037e3 (patch)
treef4eb0ef63878f0caee9b8331df924a94f6d63882
parent92f69e582e15bf281ff1ab3ccc7abdd8392550a3 (diff)
downloadlwn-e45a178e9e285c86265611a56705a1e6444037e3.tar.gz
lwn-e45a178e9e285c86265611a56705a1e6444037e3.zip
pwm: Restore initial state if a legacy callback fails
It is not entirely accurate to go back to the initial state after e.g. .enable() failed, as .config() still modified the hardware, but this same inconsistency exists for drivers that implement .apply(). Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
-rw-r--r--drivers/pwm/core.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index dedf38a81bf9..57b8cedfec3f 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -526,10 +526,8 @@ static int pwm_apply_legacy(struct pwm_chip *chip, struct pwm_device *pwm,
const struct pwm_state *state)
{
int err;
+ struct pwm_state initial_state = pwm->state;
- /*
- * FIXME: restore the initial state in case of error.
- */
if (state->polarity != pwm->state.polarity) {
if (!chip->ops->set_polarity)
return -EINVAL;
@@ -550,7 +548,7 @@ static int pwm_apply_legacy(struct pwm_chip *chip, struct pwm_device *pwm,
err = chip->ops->set_polarity(chip, pwm, state->polarity);
if (err)
- return err;
+ goto rollback;
pwm->state.polarity = state->polarity;
}
@@ -573,7 +571,7 @@ static int pwm_apply_legacy(struct pwm_chip *chip, struct pwm_device *pwm,
state->duty_cycle,
state->period);
if (err)
- return err;
+ goto rollback;
pwm->state.period = state->period;
pwm->state.duty_cycle = state->duty_cycle;
@@ -581,10 +579,14 @@ static int pwm_apply_legacy(struct pwm_chip *chip, struct pwm_device *pwm,
if (!pwm->state.enabled) {
err = chip->ops->enable(chip, pwm);
if (err)
- return err;
+ goto rollback;
}
return 0;
+
+rollback:
+ pwm->state = initial_state;
+ return err;
}
/**