Skip to content

Commit ec89572

Browse files
committed
Merge tag 'hwmon-for-v7.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon fixes from Guenter Roeck: - ads7871: Fix endianness bug in 16-bit register reads - lm75: Fix configuration register writes and AS6200/TMP112 setup and alarm handling - lm63: Fix TOCTOU problems - corsair-psu: Close HID device on probe errors - ltc2992: Fix overflow and threshold range - Documentation: fix link to ideapad-laptop.c file - Remove stale CONFIG_SENSORS_SBRMI Makefile reference * tag 'hwmon-for-v7.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: hwmon: (ads7871) Fix endianness bug in 16-bit register reads hwmon: (lm75) Fix configuration register writes. hwmon: (lm75) Fix AS6200 and TMP112 setup and alarm handling hwmon: (lm63) Add locking to avoid TOCTOU hwmon: (corsair-psu) Close HID device on probe errors hwmon: Remove stale CONFIG_SENSORS_SBRMI Makefile reference Documentation: hwmon: fix link to ideapad-laptop.c file hwmon: (ltc2992) Fix u32 overflow in power read path hwmon: (ltc2992) Clamp threshold writes to hardware range
2 parents 234d72a + 99076a1 commit ec89572

7 files changed

Lines changed: 76 additions & 29 deletions

File tree

Documentation/hwmon/yogafan.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,4 @@ References
135135

136136
4. **Lenovo IdeaPad Laptop Driver:** Reference for DMI-based hardware
137137
feature gating in Lenovo laptops.
138-
https://github.com/torvalds/linux/blob/master/drivers/platform/x86/ideapad-laptop.c
138+
https://github.com/torvalds/linux/blob/master/drivers/platform/x86/lenovo/ideapad-laptop.c

drivers/hwmon/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o
201201
obj-$(CONFIG_SENSORS_QNAP_MCU_HWMON) += qnap-mcu-hwmon.o
202202
obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o
203203
obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o
204-
obj-$(CONFIG_SENSORS_SBRMI) += sbrmi.o
205204
obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
206205
obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
207206
obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o

drivers/hwmon/ads7871.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,13 @@ static int ads7871_read_reg8(struct spi_device *spi, int reg)
7777
static int ads7871_read_reg16(struct spi_device *spi, int reg)
7878
{
7979
int ret;
80+
8081
reg = reg | INST_READ_BM | INST_16BIT_BM;
8182
ret = spi_w8r16(spi, reg);
82-
return ret;
83+
if (ret < 0)
84+
return ret;
85+
86+
return le16_to_cpu((__force __le16)ret);
8387
}
8488

8589
static int ads7871_write_reg8(struct spi_device *spi, int reg, u8 val)

drivers/hwmon/corsair-psu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,13 +796,13 @@ static int corsairpsu_probe(struct hid_device *hdev, const struct hid_device_id
796796
ret = corsairpsu_init(priv);
797797
if (ret < 0) {
798798
dev_err(&hdev->dev, "unable to initialize device (%d)\n", ret);
799-
goto fail_and_stop;
799+
goto fail_and_close;
800800
}
801801

802802
ret = corsairpsu_fwinfo(priv);
803803
if (ret < 0) {
804804
dev_err(&hdev->dev, "unable to query firmware (%d)\n", ret);
805-
goto fail_and_stop;
805+
goto fail_and_close;
806806
}
807807

808808
corsairpsu_get_criticals(priv);

drivers/hwmon/lm63.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,13 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
333333
{
334334
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
335335
struct lm63_data *data = lm63_update_device(dev);
336-
return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index]));
336+
int fan;
337+
338+
mutex_lock(&data->update_lock);
339+
fan = FAN_FROM_REG(data->fan[attr->index]);
340+
mutex_unlock(&data->update_lock);
341+
342+
return sprintf(buf, "%d\n", fan);
337343
}
338344

339345
static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
@@ -366,12 +372,14 @@ static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr,
366372
int nr = attr->index;
367373
int pwm;
368374

375+
mutex_lock(&data->update_lock);
369376
if (data->pwm_highres)
370377
pwm = data->pwm1[nr];
371378
else
372379
pwm = data->pwm1[nr] >= 2 * data->pwm1_freq ?
373380
255 : (data->pwm1[nr] * 255 + data->pwm1_freq) /
374381
(2 * data->pwm1_freq);
382+
mutex_unlock(&data->update_lock);
375383

376384
return sprintf(buf, "%d\n", pwm);
377385
}
@@ -529,6 +537,7 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
529537
int nr = attr->index;
530538
int temp;
531539

540+
mutex_lock(&data->update_lock);
532541
if (!nr) {
533542
/*
534543
* Use unsigned temperature unless its value is zero.
@@ -544,7 +553,10 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
544553
else
545554
temp = TEMP11_FROM_REG(data->temp11[nr]);
546555
}
547-
return sprintf(buf, "%d\n", temp + data->temp2_offset);
556+
temp += data->temp2_offset;
557+
mutex_unlock(&data->update_lock);
558+
559+
return sprintf(buf, "%d\n", temp);
548560
}
549561

550562
static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
@@ -592,20 +604,29 @@ static ssize_t temp2_crit_hyst_show(struct device *dev,
592604
struct device_attribute *dummy, char *buf)
593605
{
594606
struct lm63_data *data = lm63_update_device(dev);
595-
return sprintf(buf, "%d\n", temp8_from_reg(data, 2)
596-
+ data->temp2_offset
597-
- TEMP8_FROM_REG(data->temp2_crit_hyst));
607+
int temp;
608+
609+
mutex_lock(&data->update_lock);
610+
temp = temp8_from_reg(data, 2) + data->temp2_offset
611+
- TEMP8_FROM_REG(data->temp2_crit_hyst);
612+
mutex_unlock(&data->update_lock);
613+
614+
return sprintf(buf, "%d\n", temp);
598615
}
599616

600617
static ssize_t show_lut_temp_hyst(struct device *dev,
601618
struct device_attribute *devattr, char *buf)
602619
{
603620
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
604621
struct lm63_data *data = lm63_update_device(dev);
622+
int temp;
605623

606-
return sprintf(buf, "%d\n", lut_temp_from_reg(data, attr->index)
607-
+ data->temp2_offset
608-
- TEMP8_FROM_REG(data->lut_temp_hyst));
624+
mutex_lock(&data->update_lock);
625+
temp = lut_temp_from_reg(data, attr->index) + data->temp2_offset
626+
- TEMP8_FROM_REG(data->lut_temp_hyst);
627+
mutex_unlock(&data->update_lock);
628+
629+
return sprintf(buf, "%d\n", temp);
609630
}
610631

611632
/*
@@ -616,7 +637,7 @@ static ssize_t temp2_crit_hyst_store(struct device *dev,
616637
struct device_attribute *dummy,
617638
const char *buf, size_t count)
618639
{
619-
struct lm63_data *data = dev_get_drvdata(dev);
640+
struct lm63_data *data = lm63_update_device(dev);
620641
struct i2c_client *client = data->client;
621642
long val;
622643
int err;

drivers/hwmon/lm75.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ static const struct lm75_params device_params[] = {
137137
},
138138
[as6200] = {
139139
.config_reg_16bits = true,
140-
.set_mask = 0x94C0, /* 8 sample/s, 4 CF, positive polarity */
140+
.set_mask = 0xC010, /* 8 sample/s, 4 CF */
141141
.default_resolution = 12,
142142
.default_sample_time = 125,
143143
.num_sample_times = 4,
@@ -286,8 +286,8 @@ static const struct lm75_params device_params[] = {
286286
},
287287
[tmp112] = {
288288
.config_reg_16bits = true,
289-
.set_mask = 0x60C0, /* 12-bit mode, 8 samples / second */
290-
.clr_mask = 1 << 15, /* no one-shot mode*/
289+
.set_mask = 0xC060, /* 12-bit mode, 8 samples / second */
290+
.clr_mask = 1 << 7, /* no one-shot mode*/
291291
.default_resolution = 12,
292292
.default_sample_time = 125,
293293
.num_sample_times = 4,
@@ -353,7 +353,7 @@ static inline int lm75_write_config(struct lm75_data *data, u16 set_mask,
353353
u16 clr_mask)
354354
{
355355
return regmap_update_bits(data->regmap, LM75_REG_CONF,
356-
clr_mask | LM75_SHUTDOWN, set_mask);
356+
clr_mask | set_mask | LM75_SHUTDOWN, set_mask);
357357
}
358358

359359
static irqreturn_t lm75_alarm_handler(int irq, void *private)
@@ -416,7 +416,7 @@ static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
416416
switch (data->kind) {
417417
case as6200:
418418
case tmp112:
419-
*val = (regval >> 13) & 0x1;
419+
*val = !!(regval & BIT(13)) == !!(regval & BIT(2));
420420
break;
421421
default:
422422
return -EINVAL;

drivers/hwmon/ltc2992.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -431,10 +431,16 @@ static int ltc2992_get_voltage(struct ltc2992_state *st, u32 reg, u32 scale, lon
431431

432432
static int ltc2992_set_voltage(struct ltc2992_state *st, u32 reg, u32 scale, long val)
433433
{
434-
val = DIV_ROUND_CLOSEST(val * 1000, scale);
435-
val = val << 4;
434+
u32 reg_val;
435+
long vmax;
436+
437+
vmax = DIV_ROUND_CLOSEST_ULL(0xFFFULL * scale, 1000);
438+
val = max(val, 0L);
439+
val = min(val, vmax);
440+
reg_val = min(DIV_ROUND_CLOSEST_ULL((u64)val * 1000, scale),
441+
0xFFFULL) << 4;
436442

437-
return ltc2992_write_reg(st, reg, 2, val);
443+
return ltc2992_write_reg(st, reg, 2, reg_val);
438444
}
439445

440446
static int ltc2992_read_gpio_alarm(struct ltc2992_state *st, int nr_gpio, u32 attr, long *val)
@@ -559,9 +565,15 @@ static int ltc2992_get_current(struct ltc2992_state *st, u32 reg, u32 channel, l
559565
static int ltc2992_set_current(struct ltc2992_state *st, u32 reg, u32 channel, long val)
560566
{
561567
u32 reg_val;
568+
long cmax;
562569

563-
reg_val = DIV_ROUND_CLOSEST(val * st->r_sense_uohm[channel], LTC2992_IADC_NANOV_LSB);
564-
reg_val = reg_val << 4;
570+
cmax = DIV_ROUND_CLOSEST_ULL(0xFFFULL * LTC2992_IADC_NANOV_LSB,
571+
st->r_sense_uohm[channel]);
572+
val = max(val, 0L);
573+
val = min(val, cmax);
574+
reg_val = min(DIV_ROUND_CLOSEST_ULL((u64)val * st->r_sense_uohm[channel],
575+
LTC2992_IADC_NANOV_LSB),
576+
0xFFFULL) << 4;
565577

566578
return ltc2992_write_reg(st, reg, 2, reg_val);
567579
}
@@ -625,18 +637,29 @@ static int ltc2992_get_power(struct ltc2992_state *st, u32 reg, u32 channel, lon
625637
if (reg_val < 0)
626638
return reg_val;
627639

628-
*val = mul_u64_u32_div(reg_val, LTC2992_VADC_UV_LSB * LTC2992_IADC_NANOV_LSB,
629-
st->r_sense_uohm[channel] * 1000);
640+
*val = mul_u64_u32_div(reg_val,
641+
LTC2992_VADC_UV_LSB / 1000 *
642+
LTC2992_IADC_NANOV_LSB,
643+
st->r_sense_uohm[channel]);
630644

631645
return 0;
632646
}
633647

634648
static int ltc2992_set_power(struct ltc2992_state *st, u32 reg, u32 channel, long val)
635649
{
636650
u32 reg_val;
637-
638-
reg_val = mul_u64_u32_div(val, st->r_sense_uohm[channel] * 1000,
639-
LTC2992_VADC_UV_LSB * LTC2992_IADC_NANOV_LSB);
651+
u64 pmax, uval;
652+
653+
uval = max(val, 0L);
654+
pmax = mul_u64_u32_div(0xFFFFFFULL,
655+
LTC2992_VADC_UV_LSB / 1000 *
656+
LTC2992_IADC_NANOV_LSB,
657+
st->r_sense_uohm[channel]);
658+
uval = min(uval, pmax);
659+
reg_val = min(mul_u64_u32_div(uval, st->r_sense_uohm[channel],
660+
LTC2992_VADC_UV_LSB / 1000 *
661+
LTC2992_IADC_NANOV_LSB),
662+
0xFFFFFFULL);
640663

641664
return ltc2992_write_reg(st, reg, 3, reg_val);
642665
}

0 commit comments

Comments
 (0)