mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
hwmon fixes for v7.2-rc2
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEiHPvMQj9QTOCiqgVyx8mb86fmYEFAmpGaa0ACgkQyx8mb86f mYGZAw/+JjAS7LyUalHftEL2FCoK+yrTHBE86JZxcf+WDLh52+WSjAeAjbAwmeSv 2o6lWRPt0BaHSS0dTT5JZ7tCRn8swIdoCUQys8AFDTMNIaLnrgiS3qJLm0WP1I1U dLzC2L8DWajeWtyvFPJT0H7Bq7AX/hOpCwJICMu9bPCP1FwafrUgkRCqmWAb2AS9 vmLrmqGphehRbB47qw0yuoDb1rttCWfWIYqyVyBzy4uJP5XtdJt9+DyQXysP3vCD 8lAIVxLr8eSSYPjvL15mD7VT5JJwYpiN2VaI/ZwqPpAochvT4BvwirTVzUFe0OF8 ZxlHX0zQG0EW2SU5hxQ1VlqFi38u4M5qlmf+FSWJyPaxde5PFFtrl6SONy5Dflvi IDVPFTm2MS3FWjzGYSswUcAshqI+AtQIhi/9QsO4kME8SSLRdnvTBneGpnVpZHQe V2RlnnnhwS2OJK+1yIe7lDyFN7alE+mREB8RnOHlr/yLX8fM3LzzhtnmSKpqo0Aq bTYsm+lwd3sefAuxmcrKJ5YLbv41clNQzoMMuhglKqF/HS1eX+WABOE8MVVfGL/V CBjFNBw9iIY7H9jTBR+3OMx1tanmUyf4dga/vggzXOhMVRGwUNkaIe+zS/d6iaTr GujoVJBXjd0RCHUxxYuvRa+CUkbuUARRUMOrSlYTFQkzaooTlAE= =wyCy -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
a9d4dd7424
|
|
@ -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.
|
||||
======================= ==========================================
|
||||
============================== ==========================================================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1917,6 +1917,7 @@ static int w83793_probe(struct i2c_client *client)
|
|||
|
||||
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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user