mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 13:43:51 +00:00
pwm: Fixes for v6.3-rc6
These are some fixes to make sure the PWM state structure is always initialized to a known state. Prior to this it could happen in some situations that random data from the stack would leak into the data structure and cause subtle bugs. -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEEiOrDCAFJzPfAjcif3SOs138+s6EFAmQuwbMZHHRoaWVycnku cmVkaW5nQGdtYWlsLmNvbQAKCRDdI6zXfz6zobXUEACTnBZ6rnHVXvUBkyqeAoFf OAf9h4t39zYjN+cAU66nXJcZiBbWBO/r6CY6rsR+WErX4X41Fjb/mSHzkYIqb7ZF 4kY7HpYRxAew8y7RQQvbLQRG0u8++SJ4YtuJScGrRcKxL1OILqK8S91YzKSIvIh1 MYoIwHrGG9rSC+uKoJCDkOKfVenhZSiOXNXDvyIrlr6UjFC4QzGcTsAO1x8lFFNA w4szK9AXPgJdlSInsfUUiznk6q52Scl62+HSl5yHHijzMqxUm7UN1UNZ+demiG0U ujo8hw1nRuwXKpM7mmCRiELBdhVUyi3JLMbNCd+Q0GAYbQaIcEAkckL/zYEqtuDb hR2/32wMvXOLWY585L0LKqSJ5pFAkQ0g4PIAgqSRO44cG6r6yQ4NjkQGC4NKCIGS z9yyYZcBpWaOA1jHM3NZSWhN13ib3ES66a8ByKeA9PWwYuqqAbIHpIyL9MsFRWzL n2uCWLkByWY3NwM9nLRnwdMswtLffXuIbLhlt1x2M9cAVOQPZwlxeIQVbm/A0Low hFIRHYvPNfSiKaw7RBZBshQEwX6LCLmfeOUoX8KSF9/YdeBMJYOEe+OVM8h+P9hJ eESqDeM8p8hlsfk+gf/QYWu6ub52Cwv0uS1L/gHAsezJtjY1Qf1hnU/Bmv54sGoM lR/EjNJFtQiwi6uJDuCqVQ== =w7D4 -----END PGP SIGNATURE----- Merge tag 'pwm/for-6.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm Pull pwm fixes from Thierry Reding: "These are some fixes to make sure the PWM state structure is always initialized to a known state. Prior to this it could happen in some situations that random data from the stack would leak into the data structure and cause subtle bugs" * tag 'pwm/for-6.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: pwm: Zero-initialize the pwm_state passed to driver's .get_state() pwm: meson: Explicitly set .polarity in .get_state() pwm: sprd: Explicitly set .polarity in .get_state() pwm: iqs620a: Explicitly set .polarity in .get_state() pwm: cros-ec: Explicitly set .polarity in .get_state() pwm: hibvt: Explicitly set .polarity in .get_state()
This commit is contained in:
commit
ae52f79790
@ -115,7 +115,14 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
|
||||
}
|
||||
|
||||
if (pwm->chip->ops->get_state) {
|
||||
struct pwm_state state;
|
||||
/*
|
||||
* Zero-initialize state because most drivers are unaware of
|
||||
* .usage_power. The other members of state are supposed to be
|
||||
* set by lowlevel drivers. We still initialize the whole
|
||||
* structure for simplicity even though this might paper over
|
||||
* faulty implementations of .get_state().
|
||||
*/
|
||||
struct pwm_state state = { 0, };
|
||||
|
||||
err = pwm->chip->ops->get_state(pwm->chip, pwm, &state);
|
||||
trace_pwm_get(pwm, &state, err);
|
||||
@ -448,7 +455,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
|
||||
{
|
||||
struct pwm_state *last = &pwm->last;
|
||||
struct pwm_chip *chip = pwm->chip;
|
||||
struct pwm_state s1, s2;
|
||||
struct pwm_state s1 = { 0 }, s2 = { 0 };
|
||||
int err;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_PWM_DEBUG))
|
||||
@ -530,6 +537,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
|
||||
return;
|
||||
}
|
||||
|
||||
*last = (struct pwm_state){ 0 };
|
||||
err = chip->ops->get_state(chip, pwm, last);
|
||||
trace_pwm_get(pwm, last, err);
|
||||
if (err)
|
||||
|
@ -198,6 +198,7 @@ static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
state->enabled = (ret > 0);
|
||||
state->period = EC_PWM_MAX_DUTY;
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
/*
|
||||
* Note that "disabled" and "duty cycle == 0" are treated the same. If
|
||||
|
@ -146,6 +146,7 @@ static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
|
||||
state->enabled = (PWM_ENABLE_MASK & value);
|
||||
state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -126,6 +126,7 @@ static int iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
mutex_unlock(&iqs620_pwm->lock);
|
||||
|
||||
state->period = IQS620_PWM_PERIOD_NS;
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -162,6 +162,12 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
|
||||
duty = state->duty_cycle;
|
||||
period = state->period;
|
||||
|
||||
/*
|
||||
* Note this is wrong. The result is an output wave that isn't really
|
||||
* inverted and so is wrongly identified by .get_state as normal.
|
||||
* Fixing this needs some care however as some machines might rely on
|
||||
* this.
|
||||
*/
|
||||
if (state->polarity == PWM_POLARITY_INVERSED)
|
||||
duty = period - duty;
|
||||
|
||||
@ -358,6 +364,8 @@ static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
state->duty_cycle = 0;
|
||||
}
|
||||
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,7 @@ static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
duty = val & SPRD_PWM_DUTY_MSK;
|
||||
tmp = (prescale + 1) * NSEC_PER_SEC * duty;
|
||||
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate);
|
||||
state->polarity = PWM_POLARITY_NORMAL;
|
||||
|
||||
/* Disable PWM clocks if the PWM channel is not in enable state. */
|
||||
if (!state->enabled)
|
||||
|
Loading…
Reference in New Issue
Block a user