Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'hwmon-for-linus-v4.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:
"Fixes:

- Drop reference to obsolete maintainer tree

- Fix overflow bug in pmbus driver

- Fix SMBUS timeout problem in jc42 driver

For the SMBUS timeout handling, we had a brief discussion if this
should be considered a bug fix or a feature. Peter says "it fixes real
problems where the application misbehave due to faulty content when
reading from an eeprom", and he needs the patch in his company's v4.14
images. This is good enough for me and warrants backport to stable
kernels"

* tag 'hwmon-for-linus-v4.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
hwmon: (jc42) optionally try to disable the SMBUS timeout
hwmon: (pmbus) Use 64bit math for DIRECT format values
hwmon: Drop reference to Jean's tree

+37 -10
+4
Documentation/devicetree/bindings/hwmon/jc42.txt
··· 34 34 35 35 - reg: I2C address 36 36 37 + Optional properties: 38 + - smbus-timeout-disable: When set, the smbus timeout function will be disabled. 39 + This is not supported on all chips. 40 + 37 41 Example: 38 42 39 43 temp-sensor@1a {
-1
MAINTAINERS
··· 6174 6174 M: Guenter Roeck <linux@roeck-us.net> 6175 6175 L: linux-hwmon@vger.kernel.org 6176 6176 W: http://hwmon.wiki.kernel.org/ 6177 - T: quilt http://jdelvare.nerim.net/devel/linux/jdelvare-hwmon/ 6178 6177 T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git 6179 6178 S: Maintained 6180 6179 F: Documentation/hwmon/
+21
drivers/hwmon/jc42.c
··· 22 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 23 */ 24 24 25 + #include <linux/bitops.h> 25 26 #include <linux/module.h> 26 27 #include <linux/init.h> 27 28 #include <linux/slab.h> ··· 46 45 #define JC42_REG_TEMP 0x05 47 46 #define JC42_REG_MANID 0x06 48 47 #define JC42_REG_DEVICEID 0x07 48 + #define JC42_REG_SMBUS 0x22 /* NXP and Atmel, possibly others? */ 49 49 50 50 /* Status bits in temperature register */ 51 51 #define JC42_ALARM_CRIT_BIT 15 ··· 76 74 #define STM_MANID 0x104a /* ST Microelectronics */ 77 75 #define GT_MANID 0x1c68 /* Giantec */ 78 76 #define GT_MANID2 0x132d /* Giantec, 2nd mfg ID */ 77 + 78 + /* SMBUS register */ 79 + #define SMBUS_STMOUT BIT(7) /* SMBus time-out, active low */ 79 80 80 81 /* Supported chips */ 81 82 ··· 499 494 return cap; 500 495 501 496 data->extended = !!(cap & JC42_CAP_RANGE); 497 + 498 + if (device_property_read_bool(dev, "smbus-timeout-disable")) { 499 + int smbus; 500 + 501 + /* 502 + * Not all chips support this register, but from a 503 + * quick read of various datasheets no chip appears 504 + * incompatible with the below attempt to disable 505 + * the timeout. And the whole thing is opt-in... 506 + */ 507 + smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS); 508 + if (smbus < 0) 509 + return smbus; 510 + i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS, 511 + smbus | SMBUS_STMOUT); 512 + } 502 513 503 514 config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); 504 515 if (config < 0)
+12 -9
drivers/hwmon/pmbus/pmbus_core.c
··· 21 21 22 22 #include <linux/debugfs.h> 23 23 #include <linux/kernel.h> 24 + #include <linux/math64.h> 24 25 #include <linux/module.h> 25 26 #include <linux/init.h> 26 27 #include <linux/err.h> ··· 500 499 static long pmbus_reg2data_direct(struct pmbus_data *data, 501 500 struct pmbus_sensor *sensor) 502 501 { 503 - long val = (s16) sensor->data; 504 - long m, b, R; 502 + s64 b, val = (s16)sensor->data; 503 + s32 m, R; 505 504 506 505 m = data->info->m[sensor->class]; 507 506 b = data->info->b[sensor->class]; ··· 529 528 R--; 530 529 } 531 530 while (R < 0) { 532 - val = DIV_ROUND_CLOSEST(val, 10); 531 + val = div_s64(val + 5LL, 10L); /* round closest */ 533 532 R++; 534 533 } 535 534 536 - return (val - b) / m; 535 + val = div_s64(val - b, m); 536 + return clamp_val(val, LONG_MIN, LONG_MAX); 537 537 } 538 538 539 539 /* ··· 658 656 static u16 pmbus_data2reg_direct(struct pmbus_data *data, 659 657 struct pmbus_sensor *sensor, long val) 660 658 { 661 - long m, b, R; 659 + s64 b, val64 = val; 660 + s32 m, R; 662 661 663 662 m = data->info->m[sensor->class]; 664 663 b = data->info->b[sensor->class]; ··· 676 673 R -= 3; /* Adjust R and b for data in milli-units */ 677 674 b *= 1000; 678 675 } 679 - val = val * m + b; 676 + val64 = val64 * m + b; 680 677 681 678 while (R > 0) { 682 - val *= 10; 679 + val64 *= 10; 683 680 R--; 684 681 } 685 682 while (R < 0) { 686 - val = DIV_ROUND_CLOSEST(val, 10); 683 + val64 = div_s64(val64 + 5LL, 10L); /* round closest */ 687 684 R++; 688 685 } 689 686 690 - return val; 687 + return (u16)clamp_val(val64, S16_MIN, S16_MAX); 691 688 } 692 689 693 690 static u16 pmbus_data2reg_vid(struct pmbus_data *data,