On Fri, Aug 07, 2020 at 09:28:31AM +0200, Michael Walle wrote: > Hi Uwe, Hi Lee, > > Am 2020-08-06 10:40, schrieb Uwe Kleine-König: > > On Mon, Aug 03, 2020 at 11:35:52AM +0200, Michael Walle wrote: > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > > index 7dbcf6973d33..a0d50d70c3b9 100644 > > > --- a/drivers/pwm/Kconfig > > > +++ b/drivers/pwm/Kconfig > > > @@ -428,6 +428,16 @@ config PWM_SIFIVE > > > To compile this driver as a module, choose M here: the module > > > will be called pwm-sifive. > > > > > > +config PWM_SL28CPLD > > > + tristate "Kontron sl28cpld PWM support" > > > + select MFD_SIMPLE_MFD_I2C > > > > Is it sensible to present this option to everyone? Maybe > > > > depends on SOME_SYMBOL_ONLY_TRUE_ON_SL28CPLD || COMPILE_TEST > > Because there is now no real MFD driver anymore, there is also > no symbol for that. The closest would be ARCH_ARM64 but I don't > think that is a good idea. > > Lee, what do you think about adding a symbol to the MFD, which > selects MFD_SIMPLE_MFD_I2C but doesn't enable any C modules? > > I.e. > config MFD_SL28CPLD > tristate "Kontron sl28cpld" > select MFD_SIMPLE_MFD_I2C > help > Say yes here to add support for the Kontron sl28cpld board > management controller. > > Then all the other device driver could depend on the MFD_SL28CPLD > symbol. > > [..] > > > > +static void sl28cpld_pwm_get_state(struct pwm_chip *chip, > > > + struct pwm_device *pwm, > > > + struct pwm_state *state) > > > +{ > > > + struct sl28cpld_pwm *priv = dev_get_drvdata(chip->dev); > > > + unsigned int reg; > > > + int prescaler; > > > + > > > + sl28cpld_pwm_read(priv, SL28CPLD_PWM_CTRL, ®); > > > + > > > + state->enabled = reg & SL28CPLD_PWM_CTRL_ENABLE; > > > + > > > + prescaler = FIELD_GET(SL28CPLD_PWM_CTRL_PRESCALER_MASK, reg); > > > + state->period = SL28CPLD_PWM_PERIOD(prescaler); > > > + > > > + sl28cpld_pwm_read(priv, SL28CPLD_PWM_CYCLE, ®); > > > + state->duty_cycle = SL28CPLD_PWM_TO_DUTY_CYCLE(reg); > > > > Should reg be masked to SL28CPLD_PWM_CYCLE_MAX, or is it guaranteed that > > the upper bits are zero? > > Mh, the hardware guarantees that bit7 is zero. So masking with > SL28CPLD_PWM_CYCLE_MAX won't buy us much. But what I could think > could go wrong is this: someone set the prescaler to != 0 and the > duty cycle to a value greater than the max value for this particular > prescaler mode. For the above calculations this would result in a > duty_cycle greater than the period, if I'm not mistaken. > > The behavior of the hardware is undefined in that case (at the moment > it will be always on, I guess). So this isn't a valid setting. > Nevertheless it might happen. So what about the following: > > state->duty_cycle = min(state->duty_cycle, state->period); If you care about this: This can also happen (at least shortly) in sl28cpld_pwm_apply() as you write SL28CPLD_PWM_CTRL before SL28CPLD_PWM_CYCLE there. I wonder if we want to sanitize the values returned from driver's .get_state in the core; or scream loud (maybe only if PWM_DEBUG is on). Something like: if (state->enabled && state->duty_cycle > state->period) { if (IS_ENABLED(CONFIG_PWM_DEBUG)) dev_warn(chip->dev, ".get_state() returned invalid setting.\n"); state->duty_cycle = state->period; } Do we want to catch state->period = 0, too? Do we interpret this as disabled? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |