Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pwm: bcm2835: Make sure the channel is enabled after pwm_request()

The .free callback cleared among others the enable bit PWENx in the
control register. When the PWM is requested later again this bit isn't
restored but the core assumes the PWM is enabled and thus skips a
request to configure the same state as before.

To fix that don't touch the hardware configuration in .free(). For
symmetry also drop .request() and configure the mode completely in
.apply().

Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com
Signed-off-by: Uwe Kleine-König <ukleinek@kernel.org>

authored by

Uwe Kleine-König and committed by
Uwe Kleine-König
cda323db a5d51e02

+3 -25
+3 -25
drivers/pwm/pwm-bcm2835.c
··· 34 34 return pwmchip_get_drvdata(chip); 35 35 } 36 36 37 - static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) 38 - { 39 - struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); 40 - u32 value; 41 - 42 - value = readl(pc->base + PWM_CONTROL); 43 - value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); 44 - value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); 45 - writel(value, pc->base + PWM_CONTROL); 46 - 47 - return 0; 48 - } 49 - 50 - static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) 51 - { 52 - struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); 53 - u32 value; 54 - 55 - value = readl(pc->base + PWM_CONTROL); 56 - value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); 57 - writel(value, pc->base + PWM_CONTROL); 58 - } 59 - 60 37 static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 61 38 const struct pwm_state *state) 62 39 { ··· 79 102 /* set polarity */ 80 103 val = readl(pc->base + PWM_CONTROL); 81 104 105 + val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); 106 + val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); 107 + 82 108 if (state->polarity == PWM_POLARITY_NORMAL) 83 109 val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); 84 110 else ··· 99 119 } 100 120 101 121 static const struct pwm_ops bcm2835_pwm_ops = { 102 - .request = bcm2835_pwm_request, 103 - .free = bcm2835_pwm_free, 104 122 .apply = bcm2835_pwm_apply, 105 123 }; 106 124