diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-07-02 05:58:35 -1000 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-07-02 05:58:35 -1000 |
| commit | a9d4dd742466cab468a950441447c614a3920aad (patch) | |
| tree | 7636eb983dfd189e951ec8972be483b3d9b55f35 | |
| parent | db78c0db411b111b438f00a1ba418e995b5bd246 (diff) | |
| parent | fe87b8dc67f1b2c64e76a66e78468c533d3c44ca (diff) | |
| download | linux-2.6-a9d4dd742466cab468a950441447c614a3920aad.tar.gz linux-2.6-a9d4dd742466cab468a950441447c614a3920aad.zip | |
Merge tag 'hwmon-for-v7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon fixes from Guenter Roeck:
- adm1275: Detect coefficient overflow, and prevent reading
uninitialized stack
- aspeed-g6-pwm-tach: Guard fan RPM calculation against divide-by-zero
- asus_atk0110: Check package count before accessing element
- ltc4283: fix malformed table docs build error
- occ: Unregister sysfs devices outside occ lock to avoid lockdep
warning
- pmbus core: Fix passing events to regulator core, and honor
vrm_version in pmbus_data2reg_vid()
- w83627hf: Remove VID sysfs files on error and remove
- w83793: remove vrm sysfs file on probe failure
- Various: Add missing 'select REGMAP_I2C' to Kconfig
* tag 'hwmon-for-v7.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
hwmon: (aspeed-g6-pwm-tach) Guard fan RPM calculation against divide-by-zero
hwmon: (pmbus) Fix passing events to regulator core
hwmon: adm1275: Detect coefficient overflow
hwmon: adm1275: Prevent reading uninitialized stack
hwmon: (max6697) add missing 'select REGMAP_I2C' to Kconfig
hwmon: (ltc2992) add missing 'select REGMAP_I2C' to Kconfig
hwmon: (max1619) add missing 'select REGMAP' to Kconfig
hwmon: (w83627hf) remove VID sysfs files on error and remove
hwmon: (w83793) remove vrm sysfs file on probe failure
hwmon: (asus_atk0110) Check package count before accessing element
docs: hwmon: ltc4283: fix malformed table docs build error
hwmon: (pmbus/core) honor vrm_version in pmbus_data2reg_vid()
hwmon: (occ) unregister sysfs devices outside occ lock
| -rw-r--r-- | Documentation/hwmon/ltc4283.rst | 4 | ||||
| -rw-r--r-- | drivers/hwmon/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/hwmon/aspeed-g6-pwm-tach.c | 5 | ||||
| -rw-r--r-- | drivers/hwmon/asus_atk0110.c | 3 | ||||
| -rw-r--r-- | drivers/hwmon/occ/common.c | 34 | ||||
| -rw-r--r-- | drivers/hwmon/occ/common.h | 1 | ||||
| -rw-r--r-- | drivers/hwmon/pmbus/adm1275.c | 20 | ||||
| -rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 37 | ||||
| -rw-r--r-- | drivers/hwmon/w83627hf.c | 4 | ||||
| -rw-r--r-- | drivers/hwmon/w83793.c | 1 |
10 files changed, 91 insertions, 21 deletions
diff --git a/Documentation/hwmon/ltc4283.rst b/Documentation/hwmon/ltc4283.rst index a650c595bc8f..99b1ee05f629 100644 --- a/Documentation/hwmon/ltc4283.rst +++ b/Documentation/hwmon/ltc4283.rst @@ -256,7 +256,7 @@ these logs can be cleared by writing in the proper reset_history attribute. ``/sys/kernel/debug/i2c/i2c-[X]/[X]-addr/`` contains the following attributes: -======================= ========================================== +============================== ========================================================== power1_failed_fault_log Set to 1 by a power1 fault occurring. power1_good_input_fault_log Set to 1 by a power1 good input fault occurring at PGIO3. in11_fet_short_fault_log Set to 1 when a FET-short fault occurs. @@ -264,4 +264,4 @@ in11_fet_bad_fault_log Set to 1 when a FET-BAD fault occurs. in0_lcrit_fault_log Set to 1 by a VIN undervoltage fault occurring. in0_crit_fault_log Set to 1 by a VIN overvoltage fault occurring. curr1_crit_fault_log Set to 1 by an overcurrent fault occurring. -======================= ========================================== +============================== ========================================================== diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5c2d3ff5fce8..2bfbcc033d59 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1098,6 +1098,7 @@ config SENSORS_LTC2992 tristate "Linear Technology LTC2992" depends on I2C depends on GPIOLIB + select REGMAP_I2C help If you say yes here you get support for Linear Technology LTC2992 I2C System Monitor. The LTC2992 measures current, voltage, and @@ -1248,6 +1249,7 @@ config SENSORS_MAX16065 config SENSORS_MAX1619 tristate "Maxim MAX1619 sensor chip" depends on I2C + select REGMAP help If you say yes here you get support for MAX1619 sensor chip. @@ -1366,6 +1368,7 @@ config SENSORS_MAX6650 config SENSORS_MAX6697 tristate "Maxim MAX6697 and compatibles" depends on I2C + select REGMAP_I2C help If you say yes here you get support for MAX6581, MAX6602, MAX6622, MAX6636, MAX6689, MAX6693, MAX6694, MAX6697, MAX6698, and MAX6699 diff --git a/drivers/hwmon/aspeed-g6-pwm-tach.c b/drivers/hwmon/aspeed-g6-pwm-tach.c index 4f6e6d440dd4..5d611a8e5269 100644 --- a/drivers/hwmon/aspeed-g6-pwm-tach.c +++ b/drivers/hwmon/aspeed-g6-pwm-tach.c @@ -293,7 +293,10 @@ static int aspeed_tach_val_to_rpm(struct aspeed_pwm_tach_data *priv, u32 tach_va priv->clk_rate, tach_val, tach_div); rpm = (u64)priv->clk_rate * 60; - do_div(rpm, tach_div); + if (tach_div) + do_div(rpm, tach_div); + else + rpm = 0; return (int)rpm; } diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 109318b0434d..92afb64c09df 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -1037,6 +1037,9 @@ static int atk_ec_present(struct atk_data *data) if (obj->type != ACPI_TYPE_PACKAGE) continue; + if (!obj->package.count) + continue; + id = &obj->package.elements[0]; if (id->type != ACPI_TYPE_INTEGER) continue; diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c index 42cc6068bb08..e18e80e832fd 100644 --- a/drivers/hwmon/occ/common.c +++ b/drivers/hwmon/occ/common.c @@ -214,6 +214,11 @@ int occ_update_response(struct occ *occ) if (rc) return rc; + if (!occ->active) { + rc = -ENODEV; + goto unlock; + } + /* limit the maximum rate of polling the OCC */ if (time_after(jiffies, occ->next_update)) { rc = occ_poll(occ); @@ -222,6 +227,7 @@ int occ_update_response(struct occ *occ) rc = occ->last_error; } +unlock: mutex_unlock(&occ->lock); return rc; } @@ -1105,11 +1111,16 @@ static void occ_parse_poll_response(struct occ *occ) int occ_active(struct occ *occ, bool active) { - int rc = mutex_lock_interruptible(&occ->lock); + struct device *hwmon = NULL; + int rc = mutex_lock_interruptible(&occ->hwmon_lock); if (rc) return rc; + rc = mutex_lock_interruptible(&occ->lock); + if (rc) + goto unlock_hwmon; + if (active) { if (occ->active) { rc = -EALREADY; @@ -1154,14 +1165,17 @@ int occ_active(struct occ *occ, bool active) goto unlock; } - if (occ->hwmon) - hwmon_device_unregister(occ->hwmon); + hwmon = occ->hwmon; occ->active = false; occ->hwmon = NULL; } unlock: mutex_unlock(&occ->lock); + if (hwmon) + hwmon_device_unregister(hwmon); +unlock_hwmon: + mutex_unlock(&occ->hwmon_lock); return rc; } @@ -1170,6 +1184,7 @@ int occ_setup(struct occ *occ) int rc; mutex_init(&occ->lock); + mutex_init(&occ->hwmon_lock); occ->groups[0] = &occ->group; rc = occ_setup_sysfs(occ); @@ -1190,15 +1205,22 @@ EXPORT_SYMBOL_GPL(occ_setup); void occ_shutdown(struct occ *occ) { - mutex_lock(&occ->lock); + struct device *hwmon; occ_shutdown_sysfs(occ); - if (occ->hwmon) - hwmon_device_unregister(occ->hwmon); + mutex_lock(&occ->hwmon_lock); + mutex_lock(&occ->lock); + + hwmon = occ->hwmon; + occ->active = false; occ->hwmon = NULL; mutex_unlock(&occ->lock); + + if (hwmon) + hwmon_device_unregister(hwmon); + mutex_unlock(&occ->hwmon_lock); } EXPORT_SYMBOL_GPL(occ_shutdown); diff --git a/drivers/hwmon/occ/common.h b/drivers/hwmon/occ/common.h index 7ac4b2febce6..82f600093c7f 100644 --- a/drivers/hwmon/occ/common.h +++ b/drivers/hwmon/occ/common.h @@ -101,6 +101,7 @@ struct occ { unsigned long next_update; struct mutex lock; /* lock OCC access */ + struct mutex hwmon_lock; /* serialize hwmon registration/removal */ struct device *hwmon; struct occ_attribute *attrs; diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 2e5963fb1e12..d3c3ff85dba3 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -512,7 +512,7 @@ static int adm1275_enable_vout_temp(struct adm1275_data *data, static int adm1275_probe(struct i2c_client *client) { s32 (*config_read_fn)(const struct i2c_client *client, u8 reg); - u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; + u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1] = {0}; int config, device_config; int ret; struct pmbus_driver_info *info; @@ -839,15 +839,25 @@ static int adm1275_probe(struct i2c_client *client) info->R[PSC_VOLTAGE_OUT] = coefficients[voindex].R; } if (cindex >= 0) { + u32 m; + /* Scale current with sense resistor value */ - info->m[PSC_CURRENT_OUT] = - coefficients[cindex].m * shunt / 1000; + if (unlikely(check_mul_overflow(coefficients[cindex].m, shunt, &m))) { + dev_err(&client->dev, "Current coefficient overflow\n"); + return -EOVERFLOW; + } + info->m[PSC_CURRENT_OUT] = m / 1000; info->b[PSC_CURRENT_OUT] = coefficients[cindex].b; info->R[PSC_CURRENT_OUT] = coefficients[cindex].R; } if (pindex >= 0) { - info->m[PSC_POWER] = - coefficients[pindex].m * shunt / 1000; + u32 m; + + if (unlikely(check_mul_overflow(coefficients[pindex].m, shunt, &m))) { + dev_err(&client->dev, "Power coefficient overflow\n"); + return -EOVERFLOW; + } + info->m[PSC_POWER] = m / 1000; info->b[PSC_POWER] = coefficients[pindex].b; info->R[PSC_POWER] = coefficients[pindex].R; } diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index e8fdd799c71c..3143b9e0316c 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -1095,9 +1095,27 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data, static u16 pmbus_data2reg_vid(struct pmbus_data *data, struct pmbus_sensor *sensor, s64 val) { - val = clamp_val(val, 500, 1600); - - return 2 + DIV_ROUND_CLOSEST_ULL((1600LL - val) * 100LL, 625); + switch (data->info->vrm_version[sensor->page]) { + case vr12: + val = clamp_val(val, 250, 1520); + return 1 + DIV_ROUND_CLOSEST_ULL(val - 250, 5); + case vr13: + val = clamp_val(val, 500, 3040); + return 1 + DIV_ROUND_CLOSEST_ULL(val - 500, 10); + case imvp9: + val = clamp_val(val, 200, 2740); + return 1 + DIV_ROUND_CLOSEST_ULL(val - 200, 10); + case amd625mv: + val = clamp_val(val, 200, 1550); + return DIV_ROUND_CLOSEST_ULL((1550LL - val) * 100LL, 625); + case nvidia195mv: + val = clamp_val(val, 195, 1465); + return 1 + DIV_ROUND_CLOSEST_ULL(val - 195, 5); + case vr11: + default: + val = clamp_val(val, 500, 1600); + return 2 + DIV_ROUND_CLOSEST_ULL((1600LL - val) * 100LL, 625); + } } static u16 pmbus_data2reg(struct pmbus_data *data, @@ -3329,18 +3347,23 @@ static void pmbus_regulator_notify_worker(struct work_struct *work) int i, j; for (i = 0; i < data->info->pages; i++) { - int event; + unsigned int event; event = atomic_xchg(&data->regulator_events[i], 0); if (!event) continue; for (j = 0; j < data->info->num_regulators; j++) { - if (i == rdev_get_id(data->rdevs[j])) { + if (i != rdev_get_id(data->rdevs[j])) + continue; + while (event) { + unsigned int _event = BIT(__ffs(event)); + regulator_notifier_call_chain(data->rdevs[j], - event, NULL); - break; + _event, NULL); + event &= ~_event; } + break; } } } diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 95115d7b863e..bb993bb09f40 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c @@ -1823,6 +1823,8 @@ static int w83627hf_probe(struct platform_device *pdev) return 0; error: + device_remove_file(dev, &dev_attr_vrm); + device_remove_file(dev, &dev_attr_cpu0_vid); sysfs_remove_group(&dev->kobj, &w83627hf_group); sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); return err; @@ -1834,6 +1836,8 @@ static void w83627hf_remove(struct platform_device *pdev) hwmon_device_unregister(data->hwmon_dev); + device_remove_file(&pdev->dev, &dev_attr_vrm); + device_remove_file(&pdev->dev, &dev_attr_cpu0_vid); sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); } diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index b1f906f06ab4..a548586369e1 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1917,6 +1917,7 @@ exit_remove: for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) device_remove_file(dev, &w83793_vid[i].dev_attr); + device_remove_file(dev, &dev_attr_vrm); for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); |
