Skip to content

Commit 2ea25aa

Browse files
dlechUwe Kleine-König
authored andcommitted
pwm: core: export pwm_get_state_hw()
Export the pwm_get_state_hw() function. This is useful in cases where we want to know what the hardware is actually doing, rather than what what we requested it should do. Locking had to be rearranged to ensure that the chip is still operational before trying to access ops now that this can be called from outside the pwm core. Signed-off-by: David Lechner <dlechner@baylibre.com> Link: https://lore.kernel.org/r/20241029-pwm-export-pwm_get_state_hw-v2-1-03ba063a3230@baylibre.com [ukleinek: Add dummy for !CONFIG_PWM] Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>
1 parent fdb6292 commit 2ea25aa

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

drivers/pwm/core.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -718,40 +718,54 @@ int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state)
718718
}
719719
EXPORT_SYMBOL_GPL(pwm_apply_atomic);
720720

721-
static int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state)
721+
/**
722+
* pwm_get_state_hw() - get the current PWM state from hardware
723+
* @pwm: PWM device
724+
* @state: state to fill with the current PWM state
725+
*
726+
* Similar to pwm_get_state() but reads the current PWM state from hardware
727+
* instead of the requested state.
728+
*
729+
* Returns: 0 on success or a negative error code on failure.
730+
* Context: May sleep.
731+
*/
732+
int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state)
722733
{
723734
struct pwm_chip *chip = pwm->chip;
724735
const struct pwm_ops *ops = chip->ops;
725736
int ret = -EOPNOTSUPP;
726737

738+
might_sleep();
739+
740+
guard(pwmchip)(chip);
741+
742+
if (!chip->operational)
743+
return -ENODEV;
744+
727745
if (ops->read_waveform) {
728746
char wfhw[WFHWSIZE];
729747
struct pwm_waveform wf;
730748

731749
BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
732750

733-
scoped_guard(pwmchip, chip) {
751+
ret = __pwm_read_waveform(chip, pwm, &wfhw);
752+
if (ret)
753+
return ret;
734754

735-
ret = __pwm_read_waveform(chip, pwm, &wfhw);
736-
if (ret)
737-
return ret;
738-
739-
ret = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf);
740-
if (ret)
741-
return ret;
742-
}
755+
ret = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf);
756+
if (ret)
757+
return ret;
743758

744759
pwm_wf2state(&wf, state);
745760

746761
} else if (ops->get_state) {
747-
scoped_guard(pwmchip, chip)
748-
ret = ops->get_state(chip, pwm, state);
749-
762+
ret = ops->get_state(chip, pwm, state);
750763
trace_pwm_get(pwm, state, ret);
751764
}
752765

753766
return ret;
754767
}
768+
EXPORT_SYMBOL_GPL(pwm_get_state_hw);
755769

756770
/**
757771
* pwm_adjust_config() - adjust the current PWM config to the PWM arguments

include/linux/pwm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ int pwm_get_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf
370370
int pwm_set_waveform_might_sleep(struct pwm_device *pwm, const struct pwm_waveform *wf, bool exact);
371371
int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state);
372372
int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state);
373+
int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state);
373374
int pwm_adjust_config(struct pwm_device *pwm);
374375

375376
/**
@@ -494,6 +495,11 @@ static inline int pwm_apply_atomic(struct pwm_device *pwm,
494495
return -EOPNOTSUPP;
495496
}
496497

498+
static inline int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state)
499+
{
500+
return -EOPNOTSUPP;
501+
}
502+
497503
static inline int pwm_adjust_config(struct pwm_device *pwm)
498504
{
499505
return -EOPNOTSUPP;

0 commit comments

Comments
 (0)