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.14-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux

Pull pwm fixes from Uwe Kleine-König:
"Two fixes.

Conor Dooley found and fixed a problem in the pwm-microchip-core
driver that existed since the driver's birth in v6.5-rc1. It's about a
corner case that only happens if two pwm devices of the same chip are
set to the same long period.

The other problem is about the new pwm API that currently is only
supported by two hardware drivers. The fix prevents a NULL pointer
exception if one of the new functions is called for a pwm device with
a driver that only provides the old callbacks"

* tag 'pwm/for-6.14-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux:
pwm: Ensure callbacks exist before calling them
pwm: microchip-core: fix incorrect comparison with max period

+29 -3
+11 -2
drivers/pwm/core.c
··· 242 242 243 243 BUG_ON(WFHWSIZE < ops->sizeof_wfhw); 244 244 245 + if (!pwmchip_supports_waveform(chip)) 246 + return -EOPNOTSUPP; 247 + 245 248 if (!pwm_wf_valid(wf)) 246 249 return -EINVAL; 247 250 ··· 297 294 298 295 BUG_ON(WFHWSIZE < ops->sizeof_wfhw); 299 296 297 + if (!pwmchip_supports_waveform(chip) || !ops->read_waveform) 298 + return -EOPNOTSUPP; 299 + 300 300 guard(pwmchip)(chip); 301 301 302 302 if (!chip->operational) ··· 325 319 int err; 326 320 327 321 BUG_ON(WFHWSIZE < ops->sizeof_wfhw); 322 + 323 + if (!pwmchip_supports_waveform(chip)) 324 + return -EOPNOTSUPP; 328 325 329 326 if (!pwm_wf_valid(wf)) 330 327 return -EINVAL; ··· 601 592 state->usage_power == pwm->state.usage_power) 602 593 return 0; 603 594 604 - if (ops->write_waveform) { 595 + if (pwmchip_supports_waveform(chip)) { 605 596 struct pwm_waveform wf; 606 597 char wfhw[WFHWSIZE]; 607 598 ··· 755 746 if (!chip->operational) 756 747 return -ENODEV; 757 748 758 - if (ops->read_waveform) { 749 + if (pwmchip_supports_waveform(chip) && ops->read_waveform) { 759 750 char wfhw[WFHWSIZE]; 760 751 struct pwm_waveform wf; 761 752
+1 -1
drivers/pwm/pwm-microchip-core.c
··· 327 327 * mchp_core_pwm_calc_period(). 328 328 * The period is locked and we cannot change this, so we abort. 329 329 */ 330 - if (hw_period_steps == MCHPCOREPWM_PERIOD_STEPS_MAX) 330 + if (hw_period_steps > MCHPCOREPWM_PERIOD_STEPS_MAX) 331 331 return -EINVAL; 332 332 333 333 prescale = hw_prescale;
+17
include/linux/pwm.h
··· 347 347 struct pwm_device pwms[] __counted_by(npwm); 348 348 }; 349 349 350 + /** 351 + * pwmchip_supports_waveform() - checks if the given chip supports waveform callbacks 352 + * @chip: The pwm_chip to test 353 + * 354 + * Returns true iff the pwm chip support the waveform functions like 355 + * pwm_set_waveform_might_sleep() and pwm_round_waveform_might_sleep() 356 + */ 357 + static inline bool pwmchip_supports_waveform(struct pwm_chip *chip) 358 + { 359 + /* 360 + * only check for .write_waveform(). If that is available, 361 + * .round_waveform_tohw() and .round_waveform_fromhw() asserted to be 362 + * available, too, in pwmchip_add(). 363 + */ 364 + return chip->ops->write_waveform != NULL; 365 + } 366 + 350 367 static inline struct device *pwmchip_parent(const struct pwm_chip *chip) 351 368 { 352 369 return chip->dev.parent;