]> git.itanic.dy.fi Git - linux-stable/commitdiff
pwm: sti: Fix capture for st,pwm-num-chan < st,capture-num-chan
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Sun, 4 Feb 2024 21:20:43 +0000 (22:20 +0100)
committerSasha Levin <sashal@kernel.org>
Tue, 26 Mar 2024 22:16:40 +0000 (18:16 -0400)
[ Upstream commit 5f623835584f1c8d1030666796f40c47a448ce0b ]

The driver only used the number of pwm channels to set the pwm_chip's
npwm member. The result is that if there are more capture channels than
PWM channels specified in the device tree, only a part of the capture
channel is usable. Fix that by passing the bigger channel count to the
pwm framework. This makes it possible that the .apply() callback is
called with .hwpwm >= pwm_num_devs, catch that case and return an error
code.

Fixes: c97267ae831d ("pwm: sti: Add PWM capture callback")
Link: https://lore.kernel.org/r/20240204212043.2951852-2-u.kleine-koenig@pengutronix.de
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/pwm/pwm-sti.c

index 6cf55cf34d39f6d9df7ed4164eb8eb1c81720dc8..69b1113c6b82171ebbd73f81473571678f333c8e 100644 (file)
@@ -395,8 +395,17 @@ static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
 static int sti_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                         const struct pwm_state *state)
 {
+       struct sti_pwm_chip *pc = to_sti_pwmchip(chip);
+       struct sti_pwm_compat_data *cdata = pc->cdata;
+       struct device *dev = pc->dev;
        int err;
 
+       if (pwm->hwpwm >= cdata->pwm_num_devs) {
+               dev_err(dev, "device %u is not valid for pwm mode\n",
+                       pwm->hwpwm);
+               return -EINVAL;
+       }
+
        if (state->polarity != PWM_POLARITY_NORMAL)
                return -EINVAL;
 
@@ -646,7 +655,7 @@ static int sti_pwm_probe(struct platform_device *pdev)
 
        pc->chip.dev = dev;
        pc->chip.ops = &sti_pwm_ops;
-       pc->chip.npwm = pc->cdata->pwm_num_devs;
+       pc->chip.npwm = max(cdata->pwm_num_devs, cdata->cpt_num_devs);
 
        for (i = 0; i < cdata->cpt_num_devs; i++) {
                struct sti_cpt_ddata *ddata = &cdata->ddata[i];