|
@@ -21,6 +21,7 @@
|
|
|
|
|
|
#include <linux/debugfs.h>
|
|
|
#include <linux/kernel.h>
|
|
|
+#include <linux/math64.h>
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/err.h>
|
|
@@ -499,8 +500,8 @@ static long pmbus_reg2data_linear(struct pmbus_data *data,
|
|
|
static long pmbus_reg2data_direct(struct pmbus_data *data,
|
|
|
struct pmbus_sensor *sensor)
|
|
|
{
|
|
|
- long val = (s16) sensor->data;
|
|
|
- long m, b, R;
|
|
|
+ s64 b, val = (s16)sensor->data;
|
|
|
+ s32 m, R;
|
|
|
|
|
|
m = data->info->m[sensor->class];
|
|
|
b = data->info->b[sensor->class];
|
|
@@ -528,11 +529,12 @@ static long pmbus_reg2data_direct(struct pmbus_data *data,
|
|
|
R--;
|
|
|
}
|
|
|
while (R < 0) {
|
|
|
- val = DIV_ROUND_CLOSEST(val, 10);
|
|
|
+ val = div_s64(val + 5LL, 10L); /* round closest */
|
|
|
R++;
|
|
|
}
|
|
|
|
|
|
- return (val - b) / m;
|
|
|
+ val = div_s64(val - b, m);
|
|
|
+ return clamp_val(val, LONG_MIN, LONG_MAX);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -656,7 +658,8 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data,
|
|
|
static u16 pmbus_data2reg_direct(struct pmbus_data *data,
|
|
|
struct pmbus_sensor *sensor, long val)
|
|
|
{
|
|
|
- long m, b, R;
|
|
|
+ s64 b, val64 = val;
|
|
|
+ s32 m, R;
|
|
|
|
|
|
m = data->info->m[sensor->class];
|
|
|
b = data->info->b[sensor->class];
|
|
@@ -673,18 +676,18 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data,
|
|
|
R -= 3; /* Adjust R and b for data in milli-units */
|
|
|
b *= 1000;
|
|
|
}
|
|
|
- val = val * m + b;
|
|
|
+ val64 = val64 * m + b;
|
|
|
|
|
|
while (R > 0) {
|
|
|
- val *= 10;
|
|
|
+ val64 *= 10;
|
|
|
R--;
|
|
|
}
|
|
|
while (R < 0) {
|
|
|
- val = DIV_ROUND_CLOSEST(val, 10);
|
|
|
+ val64 = div_s64(val64 + 5LL, 10L); /* round closest */
|
|
|
R++;
|
|
|
}
|
|
|
|
|
|
- return val;
|
|
|
+ return (u16)clamp_val(val64, S16_MIN, S16_MAX);
|
|
|
}
|
|
|
|
|
|
static u16 pmbus_data2reg_vid(struct pmbus_data *data,
|