Skip to content

Commit fd8feec

Browse files
pbrkrgroeck
authored andcommitted
hwmon: (pwm-fan) Fix RPM calculation
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@konsulko.com> Link: https://lore.kernel.org/r/20201111164643.7087-1-pbarker@konsulko.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent 18e8db7 commit fd8feec

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

drivers/hwmon/pwm-fan.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,18 @@ static irqreturn_t pulse_handler(int irq, void *dev_id)
5454
static void sample_timer(struct timer_list *t)
5555
{
5656
struct pwm_fan_ctx *ctx = from_timer(ctx, t, rpm_timer);
57+
unsigned int delta = ktime_ms_delta(ktime_get(), ctx->sample_start);
5758
int pulses;
58-
u64 tmp;
5959

60-
pulses = atomic_read(&ctx->pulses);
61-
atomic_sub(pulses, &ctx->pulses);
62-
tmp = (u64)pulses * ktime_ms_delta(ktime_get(), ctx->sample_start) * 60;
63-
do_div(tmp, ctx->pulses_per_revolution * 1000);
64-
ctx->rpm = tmp;
60+
if (delta) {
61+
pulses = atomic_read(&ctx->pulses);
62+
atomic_sub(pulses, &ctx->pulses);
63+
ctx->rpm = (unsigned int)(pulses * 1000 * 60) /
64+
(ctx->pulses_per_revolution * delta);
65+
66+
ctx->sample_start = ktime_get();
67+
}
6568

66-
ctx->sample_start = ktime_get();
6769
mod_timer(&ctx->rpm_timer, jiffies + HZ);
6870
}
6971

0 commit comments

Comments
 (0)