diff options
author | Fabrice Gasnier <fabrice.gasnier@st.com> | 2019-09-18 16:54:21 +0200 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2019-09-21 03:25:10 +0200 |
commit | c91e3234c6035baf5a79763cb4fcd5d23ce75c2b (patch) | |
tree | ff657840c6b1869f809e4d2b5afc5b7bbeee93bf | |
parent | 71523d1812aca61e32e742e87ec064e3d8c615e1 (diff) | |
download | linux-stable-c91e3234c6035baf5a79763cb4fcd5d23ce75c2b.tar.gz linux-stable-c91e3234c6035baf5a79763cb4fcd5d23ce75c2b.tar.bz2 linux-stable-c91e3234c6035baf5a79763cb4fcd5d23ce75c2b.zip |
pwm: stm32-lp: Add check in case requested period cannot be achieved
LPTimer can use a 32KHz clock for counting. It depends on clock tree
configuration. In such a case, PWM output frequency range is limited.
Although unlikely, nothing prevents user from requesting a PWM frequency
above counting clock (32KHz for instance):
- This causes (prd - 1) = 0xffff to be written in ARR register later in
the apply() routine.
This results in badly configured PWM period (and also duty_cycle).
Add a check to report an error is such a case.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
-rw-r--r-- | drivers/pwm/pwm-stm32-lp.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-stm32-lp.c b/drivers/pwm/pwm-stm32-lp.c index 21cb260dc2c0..67fca62524dc 100644 --- a/drivers/pwm/pwm-stm32-lp.c +++ b/drivers/pwm/pwm-stm32-lp.c @@ -59,6 +59,12 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, /* Calculate the period and prescaler value */ div = (unsigned long long)clk_get_rate(priv->clk) * state->period; do_div(div, NSEC_PER_SEC); + if (!div) { + /* Clock is too slow to achieve requested period. */ + dev_dbg(priv->chip.dev, "Can't reach %u ns\n", state->period); + return -EINVAL; + } + prd = div; while (div > STM32_LPTIM_MAX_ARR) { presc++; |