On Wed, Nov 11, 2020 at 04:46:43PM +0000, Paul Barker wrote: > To convert the number of pulses counted into an RPM estimation, we need > to divide by the width of our measurement interval instead of > multiplying by it. If the width of the measurement interval is zero we > don't update the RPM value to avoid dividing by zero. > > We also don't need to do 64-bit division, with 32-bits we can handle a > fan running at over 4 million RPM. > > Signed-off-by: Paul Barker <pbarker@xxxxxxxxxxxx> Applied. Thanks, Guenter > --- > > Changes from v4: > > * Don't update ctx->sample_start if delta=0. > > Changes from v2: > > * Don't update the RPM value if delta=0. > > drivers/hwmon/pwm-fan.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > > base-commit: f8394f232b1eab649ce2df5c5f15b0e528c92091 > > diff --git a/drivers/hwmon/pwm-fan.c b/drivers/hwmon/pwm-fan.c > index bdba2143021a..1f63807c0399 100644 > --- a/drivers/hwmon/pwm-fan.c > +++ b/drivers/hwmon/pwm-fan.c > @@ -54,16 +54,18 @@ static irqreturn_t pulse_handler(int irq, void *dev_id) > static void sample_timer(struct timer_list *t) > { > struct pwm_fan_ctx *ctx = from_timer(ctx, t, rpm_timer); > + unsigned int delta = ktime_ms_delta(ktime_get(), ctx->sample_start); > int pulses; > - u64 tmp; > > - pulses = atomic_read(&ctx->pulses); > - atomic_sub(pulses, &ctx->pulses); > - tmp = (u64)pulses * ktime_ms_delta(ktime_get(), ctx->sample_start) * 60; > - do_div(tmp, ctx->pulses_per_revolution * 1000); > - ctx->rpm = tmp; > + if (delta) { > + pulses = atomic_read(&ctx->pulses); > + atomic_sub(pulses, &ctx->pulses); > + ctx->rpm = (unsigned int)(pulses * 1000 * 60) / > + (ctx->pulses_per_revolution * delta); > + > + ctx->sample_start = ktime_get(); > + } > > - ctx->sample_start = ktime_get(); > mod_timer(&ctx->rpm_timer, jiffies + HZ); > } >