diff options
| -rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 52a58b8b6e1b..a139940cd991 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include <linux/debugfs.h> | 22 | #include <linux/debugfs.h> |
| 23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 24 | #include <linux/math64.h> | ||
| 24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 26 | #include <linux/err.h> | 27 | #include <linux/err.h> |
| @@ -499,8 +500,8 @@ static long pmbus_reg2data_linear(struct pmbus_data *data, | |||
| 499 | static long pmbus_reg2data_direct(struct pmbus_data *data, | 500 | static long pmbus_reg2data_direct(struct pmbus_data *data, |
| 500 | struct pmbus_sensor *sensor) | 501 | struct pmbus_sensor *sensor) |
| 501 | { | 502 | { |
| 502 | long val = (s16) sensor->data; | 503 | s64 b, val = (s16)sensor->data; |
| 503 | long m, b, R; | 504 | s32 m, R; |
| 504 | 505 | ||
| 505 | m = data->info->m[sensor->class]; | 506 | m = data->info->m[sensor->class]; |
| 506 | b = data->info->b[sensor->class]; | 507 | b = data->info->b[sensor->class]; |
| @@ -528,11 +529,12 @@ static long pmbus_reg2data_direct(struct pmbus_data *data, | |||
| 528 | R--; | 529 | R--; |
| 529 | } | 530 | } |
| 530 | while (R < 0) { | 531 | while (R < 0) { |
| 531 | val = DIV_ROUND_CLOSEST(val, 10); | 532 | val = div_s64(val + 5LL, 10L); /* round closest */ |
| 532 | R++; | 533 | R++; |
| 533 | } | 534 | } |
| 534 | 535 | ||
| 535 | return (val - b) / m; | 536 | val = div_s64(val - b, m); |
| 537 | return clamp_val(val, LONG_MIN, LONG_MAX); | ||
| 536 | } | 538 | } |
| 537 | 539 | ||
| 538 | /* | 540 | /* |
| @@ -656,7 +658,8 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
| 656 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, | 658 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, |
| 657 | struct pmbus_sensor *sensor, long val) | 659 | struct pmbus_sensor *sensor, long val) |
| 658 | { | 660 | { |
| 659 | long m, b, R; | 661 | s64 b, val64 = val; |
| 662 | s32 m, R; | ||
| 660 | 663 | ||
| 661 | m = data->info->m[sensor->class]; | 664 | m = data->info->m[sensor->class]; |
| 662 | b = data->info->b[sensor->class]; | 665 | b = data->info->b[sensor->class]; |
| @@ -673,18 +676,18 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data, | |||
| 673 | R -= 3; /* Adjust R and b for data in milli-units */ | 676 | R -= 3; /* Adjust R and b for data in milli-units */ |
| 674 | b *= 1000; | 677 | b *= 1000; |
| 675 | } | 678 | } |
| 676 | val = val * m + b; | 679 | val64 = val64 * m + b; |
| 677 | 680 | ||
| 678 | while (R > 0) { | 681 | while (R > 0) { |
| 679 | val *= 10; | 682 | val64 *= 10; |
| 680 | R--; | 683 | R--; |
| 681 | } | 684 | } |
| 682 | while (R < 0) { | 685 | while (R < 0) { |
| 683 | val = DIV_ROUND_CLOSEST(val, 10); | 686 | val64 = div_s64(val64 + 5LL, 10L); /* round closest */ |
| 684 | R++; | 687 | R++; |
| 685 | } | 688 | } |
| 686 | 689 | ||
| 687 | return val; | 690 | return (u16)clamp_val(val64, S16_MIN, S16_MAX); |
| 688 | } | 691 | } |
| 689 | 692 | ||
| 690 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, | 693 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, |
