Skip to content

Commit ae52f79

Browse files
committed
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()
2 parents ac6c043 + 1271a7b commit ae52f79

File tree

6 files changed

+22
-2
lines changed

6 files changed

+22
-2
lines changed

drivers/pwm/core.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,14 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
115115
}
116116

117117
if (pwm->chip->ops->get_state) {
118-
struct pwm_state state;
118+
/*
119+
* Zero-initialize state because most drivers are unaware of
120+
* .usage_power. The other members of state are supposed to be
121+
* set by lowlevel drivers. We still initialize the whole
122+
* structure for simplicity even though this might paper over
123+
* faulty implementations of .get_state().
124+
*/
125+
struct pwm_state state = { 0, };
119126

120127
err = pwm->chip->ops->get_state(pwm->chip, pwm, &state);
121128
trace_pwm_get(pwm, &state, err);
@@ -448,7 +455,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
448455
{
449456
struct pwm_state *last = &pwm->last;
450457
struct pwm_chip *chip = pwm->chip;
451-
struct pwm_state s1, s2;
458+
struct pwm_state s1 = { 0 }, s2 = { 0 };
452459
int err;
453460

454461
if (!IS_ENABLED(CONFIG_PWM_DEBUG))
@@ -530,6 +537,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
530537
return;
531538
}
532539

540+
*last = (struct pwm_state){ 0 };
533541
err = chip->ops->get_state(chip, pwm, last);
534542
trace_pwm_get(pwm, last, err);
535543
if (err)

drivers/pwm/pwm-cros-ec.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ static int cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
198198

199199
state->enabled = (ret > 0);
200200
state->period = EC_PWM_MAX_DUTY;
201+
state->polarity = PWM_POLARITY_NORMAL;
201202

202203
/*
203204
* Note that "disabled" and "duty cycle == 0" are treated the same. If

drivers/pwm/pwm-hibvt.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ static int hibvt_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
146146

147147
value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm));
148148
state->enabled = (PWM_ENABLE_MASK & value);
149+
state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
149150

150151
return 0;
151152
}

drivers/pwm/pwm-iqs620a.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ static int iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
126126
mutex_unlock(&iqs620_pwm->lock);
127127

128128
state->period = IQS620_PWM_PERIOD_NS;
129+
state->polarity = PWM_POLARITY_NORMAL;
129130

130131
return 0;
131132
}

drivers/pwm/pwm-meson.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
162162
duty = state->duty_cycle;
163163
period = state->period;
164164

165+
/*
166+
* Note this is wrong. The result is an output wave that isn't really
167+
* inverted and so is wrongly identified by .get_state as normal.
168+
* Fixing this needs some care however as some machines might rely on
169+
* this.
170+
*/
165171
if (state->polarity == PWM_POLARITY_INVERSED)
166172
duty = period - duty;
167173

@@ -358,6 +364,8 @@ static int meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
358364
state->duty_cycle = 0;
359365
}
360366

367+
state->polarity = PWM_POLARITY_NORMAL;
368+
361369
return 0;
362370
}
363371

drivers/pwm/pwm-sprd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static int sprd_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
109109
duty = val & SPRD_PWM_DUTY_MSK;
110110
tmp = (prescale + 1) * NSEC_PER_SEC * duty;
111111
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate);
112+
state->polarity = PWM_POLARITY_NORMAL;
112113

113114
/* Disable PWM clocks if the PWM channel is not in enable state. */
114115
if (!state->enabled)

0 commit comments

Comments
 (0)