mirror of
https://github.com/torvalds/linux.git
synced 2026-05-21 21:37:25 +02:00
pwm: Ensure callbacks exist before calling them
If one of the waveform functions is called for a chip that only supports
.apply(), we want that an error code is returned and not a NULL pointer
exception.
Fixes: 6c5126c640 ("pwm: Provide new consumer API functions for waveforms")
Cc: stable@vger.kernel.org
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Tested-by: Trevor Gamblin <tgamblin@baylibre.com>
Link: https://lore.kernel.org/r/20250123172709.391349-2-u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
This commit is contained in:
parent
752b6e3af3
commit
da6b353786
|
|
@ -242,6 +242,9 @@ int pwm_round_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *
|
|||
|
||||
BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
|
||||
|
||||
if (!pwmchip_supports_waveform(chip))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!pwm_wf_valid(wf))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -294,6 +297,9 @@ int pwm_get_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf
|
|||
|
||||
BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
|
||||
|
||||
if (!pwmchip_supports_waveform(chip) || !ops->read_waveform)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
guard(pwmchip)(chip);
|
||||
|
||||
if (!chip->operational)
|
||||
|
|
@ -320,6 +326,9 @@ static int __pwm_set_waveform(struct pwm_device *pwm,
|
|||
|
||||
BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
|
||||
|
||||
if (!pwmchip_supports_waveform(chip))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!pwm_wf_valid(wf))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -592,7 +601,7 @@ static int __pwm_apply(struct pwm_device *pwm, const struct pwm_state *state)
|
|||
state->usage_power == pwm->state.usage_power)
|
||||
return 0;
|
||||
|
||||
if (ops->write_waveform) {
|
||||
if (pwmchip_supports_waveform(chip)) {
|
||||
struct pwm_waveform wf;
|
||||
char wfhw[WFHWSIZE];
|
||||
|
||||
|
|
@ -746,7 +755,7 @@ int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state)
|
|||
if (!chip->operational)
|
||||
return -ENODEV;
|
||||
|
||||
if (ops->read_waveform) {
|
||||
if (pwmchip_supports_waveform(chip) && ops->read_waveform) {
|
||||
char wfhw[WFHWSIZE];
|
||||
struct pwm_waveform wf;
|
||||
|
||||
|
|
|
|||
|
|
@ -347,6 +347,23 @@ struct pwm_chip {
|
|||
struct pwm_device pwms[] __counted_by(npwm);
|
||||
};
|
||||
|
||||
/**
|
||||
* pwmchip_supports_waveform() - checks if the given chip supports waveform callbacks
|
||||
* @chip: The pwm_chip to test
|
||||
*
|
||||
* Returns true iff the pwm chip support the waveform functions like
|
||||
* pwm_set_waveform_might_sleep() and pwm_round_waveform_might_sleep()
|
||||
*/
|
||||
static inline bool pwmchip_supports_waveform(struct pwm_chip *chip)
|
||||
{
|
||||
/*
|
||||
* only check for .write_waveform(). If that is available,
|
||||
* .round_waveform_tohw() and .round_waveform_fromhw() asserted to be
|
||||
* available, too, in pwmchip_add().
|
||||
*/
|
||||
return chip->ops->write_waveform != NULL;
|
||||
}
|
||||
|
||||
static inline struct device *pwmchip_parent(const struct pwm_chip *chip)
|
||||
{
|
||||
return chip->dev.parent;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user