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

Configure Feed

Select the types of activity you want to include in your feed.

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()

+22 -2
+10 -2
drivers/pwm/core.c
··· 115 115 } 116 116 117 117 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, }; 119 126 120 127 err = pwm->chip->ops->get_state(pwm->chip, pwm, &state); 121 128 trace_pwm_get(pwm, &state, err); ··· 455 448 { 456 449 struct pwm_state *last = &pwm->last; 457 450 struct pwm_chip *chip = pwm->chip; 458 - struct pwm_state s1, s2; 451 + struct pwm_state s1 = { 0 }, s2 = { 0 }; 459 452 int err; 460 453 461 454 if (!IS_ENABLED(CONFIG_PWM_DEBUG)) ··· 537 530 return; 538 531 } 539 532 533 + *last = (struct pwm_state){ 0 }; 540 534 err = chip->ops->get_state(chip, pwm, last); 541 535 trace_pwm_get(pwm, last, err); 542 536 if (err)
+1
drivers/pwm/pwm-cros-ec.c
··· 198 198 199 199 state->enabled = (ret > 0); 200 200 state->period = EC_PWM_MAX_DUTY; 201 + state->polarity = PWM_POLARITY_NORMAL; 201 202 202 203 /* 203 204 * Note that "disabled" and "duty cycle == 0" are treated the same. If
+1
drivers/pwm/pwm-hibvt.c
··· 146 146 147 147 value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm)); 148 148 state->enabled = (PWM_ENABLE_MASK & value); 149 + state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; 149 150 150 151 return 0; 151 152 }
+1
drivers/pwm/pwm-iqs620a.c
··· 126 126 mutex_unlock(&iqs620_pwm->lock); 127 127 128 128 state->period = IQS620_PWM_PERIOD_NS; 129 + state->polarity = PWM_POLARITY_NORMAL; 129 130 130 131 return 0; 131 132 }
+8
drivers/pwm/pwm-meson.c
··· 162 162 duty = state->duty_cycle; 163 163 period = state->period; 164 164 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 + */ 165 171 if (state->polarity == PWM_POLARITY_INVERSED) 166 172 duty = period - duty; 167 173 ··· 363 357 state->period = 0; 364 358 state->duty_cycle = 0; 365 359 } 360 + 361 + state->polarity = PWM_POLARITY_NORMAL; 366 362 367 363 return 0; 368 364 }
+1
drivers/pwm/pwm-sprd.c
··· 109 109 duty = val & SPRD_PWM_DUTY_MSK; 110 110 tmp = (prescale + 1) * NSEC_PER_SEC * duty; 111 111 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate); 112 + state->polarity = PWM_POLARITY_NORMAL; 112 113 113 114 /* Disable PWM clocks if the PWM channel is not in enable state. */ 114 115 if (!state->enabled)