Commit e26aeee8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hwmon-for-v5.8-rc6' of...

Merge tag 'hwmon-for-v5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging into master

Pull hwmon fixes from Guenter Roeck:

 - Using SCT on some Tohsiba drives causes firmware hangs. Disable its
   use in the drivetemp driver.

 - Handle potential buffer overflows in scmi and aspeed-pwm-tacho
   driver.

 - Energy reporting does not work well on all AMD CPUs. Restrict
   amd_energy to known working models.

 - Enable reading the CPU temperature on NCT6798D using undocumented
   registers.

 - Fix read errors seen if PEC is enabled in adm1275 driver.

 - Fix setting the pwm1_enable in emc2103 driver.

* tag 'hwmon-for-v5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (drivetemp) Avoid SCT usage on Toshiba DT01ACA family drives
  hwmon: (scmi) Fix potential buffer overflow in scmi_hwmon_probe()
  hwmon: (nct6775) Accept PECI Calibration as temperature source for NCT6798D
  hwmon: (adm1275) Make sure we are reading enough data for different chips
  hwmon: (emc2103) fix unable to change fan pwm1_enable attribute
  hwmon: (amd_energy) match for supported models
  hwmon: (aspeed-pwm-tacho) Avoid possible buffer overflow
parents 6cf7ccba c66ef39e
...@@ -362,7 +362,7 @@ static struct platform_driver amd_energy_driver = { ...@@ -362,7 +362,7 @@ static struct platform_driver amd_energy_driver = {
static struct platform_device *amd_energy_platdev; static struct platform_device *amd_energy_platdev;
static const struct x86_cpu_id cpu_ids[] __initconst = { static const struct x86_cpu_id cpu_ids[] __initconst = {
X86_MATCH_VENDOR_FAM(AMD, 0x17, NULL), X86_MATCH_VENDOR_FAM_MODEL(AMD, 0x17, 0x31, NULL),
{} {}
}; };
MODULE_DEVICE_TABLE(x86cpu, cpu_ids); MODULE_DEVICE_TABLE(x86cpu, cpu_ids);
......
...@@ -851,6 +851,8 @@ static int aspeed_create_fan(struct device *dev, ...@@ -851,6 +851,8 @@ static int aspeed_create_fan(struct device *dev,
ret = of_property_read_u32(child, "reg", &pwm_port); ret = of_property_read_u32(child, "reg", &pwm_port);
if (ret) if (ret)
return ret; return ret;
if (pwm_port >= ARRAY_SIZE(pwm_port_params))
return -EINVAL;
aspeed_create_pwm_port(priv, (u8)pwm_port); aspeed_create_pwm_port(priv, (u8)pwm_port);
ret = of_property_count_u8_elems(child, "cooling-levels"); ret = of_property_count_u8_elems(child, "cooling-levels");
......
...@@ -285,6 +285,42 @@ static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val) ...@@ -285,6 +285,42 @@ static int drivetemp_get_scttemp(struct drivetemp_data *st, u32 attr, long *val)
return err; return err;
} }
static const char * const sct_avoid_models[] = {
/*
* These drives will have WRITE FPDMA QUEUED command timeouts and sometimes just
* freeze until power-cycled under heavy write loads when their temperature is
* getting polled in SCT mode. The SMART mode seems to be fine, though.
*
* While only the 3 TB model (DT01ACA3) was actually caught exhibiting the
* problem let's play safe here to avoid data corruption and ban the whole
* DT01ACAx family.
* The models from this array are prefix-matched.
*/
"TOSHIBA DT01ACA",
};
static bool drivetemp_sct_avoid(struct drivetemp_data *st)
{
struct scsi_device *sdev = st->sdev;
unsigned int ctr;
if (!sdev->model)
return false;
/*
* The "model" field contains just the raw SCSI INQUIRY response
* "product identification" field, which has a width of 16 bytes.
* This field is space-filled, but is NOT NULL-terminated.
*/
for (ctr = 0; ctr < ARRAY_SIZE(sct_avoid_models); ctr++)
if (!strncmp(sdev->model, sct_avoid_models[ctr],
strlen(sct_avoid_models[ctr])))
return true;
return false;
}
static int drivetemp_identify_sata(struct drivetemp_data *st) static int drivetemp_identify_sata(struct drivetemp_data *st)
{ {
struct scsi_device *sdev = st->sdev; struct scsi_device *sdev = st->sdev;
...@@ -326,6 +362,13 @@ static int drivetemp_identify_sata(struct drivetemp_data *st) ...@@ -326,6 +362,13 @@ static int drivetemp_identify_sata(struct drivetemp_data *st)
/* bail out if this is not a SATA device */ /* bail out if this is not a SATA device */
if (!is_ata || !is_sata) if (!is_ata || !is_sata)
return -ENODEV; return -ENODEV;
if (have_sct && drivetemp_sct_avoid(st)) {
dev_notice(&sdev->sdev_gendev,
"will avoid using SCT for temperature monitoring\n");
have_sct = false;
}
if (!have_sct) if (!have_sct)
goto skip_sct; goto skip_sct;
......
...@@ -443,7 +443,7 @@ static ssize_t pwm1_enable_store(struct device *dev, ...@@ -443,7 +443,7 @@ static ssize_t pwm1_enable_store(struct device *dev,
} }
result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg);
if (result) { if (result < 0) {
count = result; count = result;
goto err; goto err;
} }
......
...@@ -786,13 +786,13 @@ static const char *const nct6798_temp_label[] = { ...@@ -786,13 +786,13 @@ static const char *const nct6798_temp_label[] = {
"Agent1 Dimm1", "Agent1 Dimm1",
"BYTE_TEMP0", "BYTE_TEMP0",
"BYTE_TEMP1", "BYTE_TEMP1",
"", "PECI Agent 0 Calibration", /* undocumented */
"", "PECI Agent 1 Calibration", /* undocumented */
"", "",
"Virtual_TEMP" "Virtual_TEMP"
}; };
#define NCT6798_TEMP_MASK 0x8fff0ffe #define NCT6798_TEMP_MASK 0xbfff0ffe
#define NCT6798_VIRT_TEMP_MASK 0x80000c00 #define NCT6798_VIRT_TEMP_MASK 0x80000c00
/* NCT6102D/NCT6106D specific data */ /* NCT6102D/NCT6106D specific data */
......
...@@ -465,6 +465,7 @@ MODULE_DEVICE_TABLE(i2c, adm1275_id); ...@@ -465,6 +465,7 @@ MODULE_DEVICE_TABLE(i2c, adm1275_id);
static int adm1275_probe(struct i2c_client *client, static int adm1275_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
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];
int config, device_config; int config, device_config;
int ret; int ret;
...@@ -510,11 +511,16 @@ static int adm1275_probe(struct i2c_client *client, ...@@ -510,11 +511,16 @@ static int adm1275_probe(struct i2c_client *client,
"Device mismatch: Configured %s, detected %s\n", "Device mismatch: Configured %s, detected %s\n",
id->name, mid->name); id->name, mid->name);
config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); if (mid->driver_data == adm1272 || mid->driver_data == adm1278 ||
mid->driver_data == adm1293 || mid->driver_data == adm1294)
config_read_fn = i2c_smbus_read_word_data;
else
config_read_fn = i2c_smbus_read_byte_data;
config = config_read_fn(client, ADM1275_PMON_CONFIG);
if (config < 0) if (config < 0)
return config; return config;
device_config = i2c_smbus_read_byte_data(client, ADM1275_DEVICE_CONFIG); device_config = config_read_fn(client, ADM1275_DEVICE_CONFIG);
if (device_config < 0) if (device_config < 0)
return device_config; return device_config;
......
...@@ -147,7 +147,7 @@ static enum hwmon_sensor_types scmi_types[] = { ...@@ -147,7 +147,7 @@ static enum hwmon_sensor_types scmi_types[] = {
[ENERGY] = hwmon_energy, [ENERGY] = hwmon_energy,
}; };
static u32 hwmon_attributes[] = { static u32 hwmon_attributes[hwmon_max] = {
[hwmon_chip] = HWMON_C_REGISTER_TZ, [hwmon_chip] = HWMON_C_REGISTER_TZ,
[hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL, [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL,
[hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL, [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment