Messages in this thread | | | Date | Sat, 15 Jul 2023 14:12:53 +0200 | From | Uwe Kleine-König <> | Subject | Re: [PATCH v5] pwm: atmel: Enable clk when pwm already enabled in bootloader |
| |
On Sat, Jul 15, 2023 at 10:36:53AM +0800, Guiting Shen wrote: > The driver would never call clk_enable() if the PWM channel was already > enabled in bootloader which lead to dump the warning message "the PWM > clock already disabled" when turning off the PWM channel. > > Add atmel_pwm_enable_clk_if_on() in probe function to enable clock if > the PWM channel was already enabled in bootloader. > > Signed-off-by: Guiting Shen <aarongt.shen@gmail.com> > --- > drivers/pwm/pwm-atmel.c | 50 +++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 48 insertions(+), 2 deletions(-) > > diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c > index cdbc23649032..4dd6e1319343 100644 > --- a/drivers/pwm/pwm-atmel.c > +++ b/drivers/pwm/pwm-atmel.c > @@ -36,7 +36,7 @@ > #define PWM_SR 0x0C > #define PWM_ISR 0x1C > /* Bit field in SR */ > -#define PWM_SR_ALL_CH_ON 0x0F > +#define PWM_SR_ALL_CH_MASK 0x0F > > /* The following register is PWM channel related registers */ > #define PWM_CH_REG_OFFSET 0x200 > @@ -464,6 +464,45 @@ static const struct of_device_id atmel_pwm_dt_ids[] = { > }; > MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids); > > +static int atmel_pwm_enable_clk_if_on(struct atmel_pwm_chip *atmel_pwm, bool on) > +{ > + unsigned int i, cnt = 0; > + int ret = 0; > + u32 sr; > + > + sr = atmel_pwm_readl(atmel_pwm, PWM_SR) & PWM_SR_ALL_CH_MASK; > + if (!sr) > + return 0; > + > + for (i = 0; i < atmel_pwm->chip.npwm; i++) { > + if (sr & (1 << i)) > + cnt++; > + }
If it's just about counting the set bits, there is the function bitmap_weight().
> + if (!on) > + goto disable_clk; > + > + for (i = 0; i < cnt; i++) { > + ret = clk_enable(atmel_pwm->clk); > + if (ret) { > + dev_err(atmel_pwm->chip.dev, > + "failed to enable clock for pwm #%d: %pe\n", > + i, ERR_PTR(ret));
The output is bogus here. If SR is say 0xc, and the second enable fails, it's about pwm #3, but then i is 1.
> + cnt = i; > + goto disable_clk; > + } > + } > + > + return 0; > + > +disable_clk: > + while (cnt--) > + clk_disable(atmel_pwm->clk); > + > + return ret; > +} > + > static int atmel_pwm_probe(struct platform_device *pdev) > { > struct atmel_pwm_chip *atmel_pwm;
Best regards Uwe
-- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ | [unhandled content-type:application/pgp-signature] | |