Hello, On Wed, Jul 10, 2024 at 10:04:07AM +0800, Binbin Zhou wrote: > diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c > new file mode 100644 > index 000000000000..17ab2a2f48ad > --- /dev/null > +++ b/drivers/pwm/pwm-loongson.c > @@ -0,0 +1,285 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Loongson PWM driver > + * > + * Author: Juxin Gao <gaojuxin@xxxxxxxxxxx> > + * Further cleanup and restructuring by: > + * Binbin Zhou <zhoubinbin@xxxxxxxxxxx> > + * > + * Copyright (C) 2017-2024 Loongson Technology Corporation Limited. > + * > + * Limitations: > + * - The buffer register value should be written before the CTRL register. > + * - When disabled the output is driven to 0 independent of the configured > + * polarity. An info about possible glitches and if a period is completed on reconfiguration or when the PWM is disabled would be great. Also if there is a publically available manual, please add a link here. > + */ > + > [...] > +static int pwm_loongson_apply(struct pwm_chip *chip, struct pwm_device *pwm, > + const struct pwm_state *state) > +{ > + int ret; > + u64 period, duty_cycle; > + bool enabled = pwm->state.enabled; > + > + if (enabled && !state->enabled) { > + pwm_loongson_disable(chip, pwm); > + return 0; > + } You can also shortcut if !pwm->state.enabled. Something like: if (!state->enabled) { if (enabled) pwm_loongson_disable(chip, pwm); return 0; } > + if (state->polarity != pwm->state.polarity) { > + ret = pwm_loongson_set_polarity(chip, pwm, state->polarity); > + if (ret) > + return ret; > + } Together with the shortcut above this is buggy. Consider: pwm_apply_might_sleep(mypwm, &(struct pwm_state){ .period = A, .duty_cycle = B, .polarity = PWM_POLARITY_NORMAL, .enabled = true}); pwm_apply_might_sleep(mypwm, &(struct pwm_state){ .period = A, .duty_cycle = B, .polarity = PWM_POLARITY_INVERSED, .enabled = false}); pwm_apply_might_sleep(mypwm, &(struct pwm_state){ .period = A, .duty_cycle = B, .polarity = PWM_POLARITY_INVERSED, .enabled = true}); After the 2nd call you left pwm_loongson_apply() early without writing the inversed polarity to the register space. In the 3rd call you have state->polarity == pwm->state.polarity and so skip configuring the polarity again. I suggest to just do pwm_loongson_set_polarity() unconditionally if state->enabled = true. > + period = min(state->period, NANOHZ_PER_HZ); > + duty_cycle = min(state->duty_cycle, NANOHZ_PER_HZ); > + > + ret = pwm_loongson_config(chip, pwm, duty_cycle, period); > + if (ret) > + return ret; > + > + if (!enabled && state->enabled) > + ret = pwm_loongson_enable(chip, pwm); > + > + return ret; > +} Best regards Uwe
Attachment:
signature.asc
Description: PGP signature