diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-07-28 17:02:11 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-07-28 17:02:11 -0700 |
commit | 2f4effd85fe9228a21bdfd037be006aa9bd7a617 (patch) | |
tree | fae7167116d2b0da759db2664babad6e02a975c6 /drivers | |
parent | c06f9091a2913f9f76e68ce3e0a7f781546034b6 (diff) | |
parent | e146503ac68418859fb063a3a0cd9ec93bc52238 (diff) |
Merge tag 'hwmon-for-v6.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon fixes from Guenter Roeck:
- k10temp: Display negative temperatures for industrial processors
- pmbus core: Fix deadlock, NULL pointer dereference, and chip enable
detection
- nct7802: Do not display PECI1 temperature if disabled
- nct6775: Fix IN scaling factors and feature detection for
NCT6798/6799
- oxp-sensors: Fix race condition during device attribute creation
- aquacomputer_d5next: Fix incorrect PWM value readout
* tag 'hwmon-for-v6.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
hwmon: (k10temp) Enable AMD3255 Proc to show negative temperature
hwmon: (pmbus_core) Fix Deadlock in pmbus_regulator_get_status
hwmon: (pmbus_core) Fix NULL pointer dereference
hwmon: (pmbus_core) Fix pmbus_is_enabled()
hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled
hwmon: (nct6775) Fix IN scaling factors for 6798/6799
hwmon: (oxp-sensors) Move tt_toggle attribute to dev_groups
hwmon: (aquacomputer_d5next) Fix incorrect PWM value readout
hwmon: (nct6775) Fix register for nct6799
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwmon/aquacomputer_d5next.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/k10temp.c | 17 | ||||
-rw-r--r-- | drivers/hwmon/nct6775-core.c | 28 | ||||
-rw-r--r-- | drivers/hwmon/nct6775-platform.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/nct6775.h | 1 | ||||
-rw-r--r-- | drivers/hwmon/nct7802.c | 2 | ||||
-rw-r--r-- | drivers/hwmon/oxp-sensors.c | 38 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 20 |
8 files changed, 76 insertions, 34 deletions
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c index a981f7086114..a997dbcb563f 100644 --- a/drivers/hwmon/aquacomputer_d5next.c +++ b/drivers/hwmon/aquacomputer_d5next.c @@ -1027,7 +1027,7 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, if (ret < 0) return ret; - *val = aqc_percent_to_pwm(ret); + *val = aqc_percent_to_pwm(*val); break; } break; diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 7b177b9fbb09..a267b11731a8 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -77,6 +77,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); #define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19) #define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16) +/* + * AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius. + * Use the model name to identify 3255 CPUs and set a flag to display negative temperature. + * Do not round off to zero for negative Tctl or Tdie values if the flag is set + */ +#define AMD_I3255_STR "3255" + struct k10temp_data { struct pci_dev *pdev; void (*read_htcreg)(struct pci_dev *pdev, u32 *regval); @@ -86,6 +93,7 @@ struct k10temp_data { u32 show_temp; bool is_zen; u32 ccd_offset; + bool disp_negative; }; #define TCTL_BIT 0 @@ -204,12 +212,12 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, switch (channel) { case 0: /* Tctl */ *val = get_raw_temp(data); - if (*val < 0) + if (*val < 0 && !data->disp_negative) *val = 0; break; case 1: /* Tdie */ *val = get_raw_temp(data) - data->temp_offset; - if (*val < 0) + if (*val < 0 && !data->disp_negative) *val = 0; break; case 2 ... 13: /* Tccd{1-12} */ @@ -405,6 +413,11 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) data->pdev = pdev; data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */ + if (boot_cpu_data.x86 == 0x17 && + strstr(boot_cpu_data.x86_model_id, AMD_I3255_STR)) { + data->disp_negative = true; + } + if (boot_cpu_data.x86 == 0x15 && ((boot_cpu_data.x86_model & 0xf0) == 0x60 || (boot_cpu_data.x86_model & 0xf0) == 0x70)) { diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c index 236dc97f4d22..08ce4984151d 100644 --- a/drivers/hwmon/nct6775-core.c +++ b/drivers/hwmon/nct6775-core.c @@ -955,14 +955,25 @@ static const u16 scale_in[15] = { 800, 800 }; -static inline long in_from_reg(u8 reg, u8 nr) +/* + * NCT6798 scaling: + * CPUVC, IN1, AVSB, 3VCC, IN0, IN8, IN4, 3VSB, VBAT, VTT, IN5, IN6, IN2, + * IN3, IN7 + * Additional scales to be added later: IN9 (800), VHIF (1600) + */ +static const u16 scale_in_6798[15] = { + 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 1600, 1600, 1600, 800, + 800, 800 +}; + +static inline long in_from_reg(u8 reg, u8 nr, const u16 *scales) { - return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100); + return DIV_ROUND_CLOSEST(reg * scales[nr], 100); } -static inline u8 in_to_reg(u32 val, u8 nr) +static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scales) { - return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255); + return clamp_val(DIV_ROUND_CLOSEST(val * 100, scales[nr]), 0, 255); } /* TSI temperatures are in 8.3 format */ @@ -1673,7 +1684,8 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) if (IS_ERR(data)) return PTR_ERR(data); - return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr)); + return sprintf(buf, "%ld\n", + in_from_reg(data->in[nr][index], nr, data->scale_in)); } static ssize_t @@ -1691,7 +1703,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf, if (err < 0) return err; mutex_lock(&data->update_lock); - data->in[nr][index] = in_to_reg(val, nr); + data->in[nr][index] = in_to_reg(val, nr, data->scale_in); err = nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], data->in[nr][index]); mutex_unlock(&data->update_lock); return err ? : count; @@ -3462,6 +3474,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, mutex_init(&data->update_lock); data->name = nct6775_device_names[data->kind]; data->bank = 0xff; /* Force initial bank selection */ + data->scale_in = scale_in; switch (data->kind) { case nct6106: @@ -3977,6 +3990,9 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, break; } + if (data->kind == nct6798 || data->kind == nct6799) + data->scale_in = scale_in_6798; + reg_temp = NCT6779_REG_TEMP; num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); if (data->kind == nct6791) { diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c index ada867d6b98a..a409d7a0b813 100644 --- a/drivers/hwmon/nct6775-platform.c +++ b/drivers/hwmon/nct6775-platform.c @@ -586,7 +586,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio int creb; int cred; - cre6 = sio_data->sio_inb(sio_data, 0xe0); + cre6 = sio_data->sio_inb(sio_data, 0xe6); sio_data->sio_select(sio_data, NCT6775_LD_12); cre0 = sio_data->sio_inb(sio_data, 0xe0); diff --git a/drivers/hwmon/nct6775.h b/drivers/hwmon/nct6775.h index 44f79c5726a9..a84c6ce7275d 100644 --- a/drivers/hwmon/nct6775.h +++ b/drivers/hwmon/nct6775.h @@ -98,6 +98,7 @@ struct nct6775_data { u8 bank; /* current register bank */ u8 in_num; /* number of in inputs we have */ u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ + const u16 *scale_in; /* internal scaling factors */ unsigned int rpm[NUM_FAN]; u16 fan_min[NUM_FAN]; u8 fan_pulses[NUM_FAN]; diff --git a/drivers/hwmon/nct7802.c b/drivers/hwmon/nct7802.c index 9339bfc02a3e..024cff151c36 100644 --- a/drivers/hwmon/nct7802.c +++ b/drivers/hwmon/nct7802.c @@ -725,7 +725,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj, if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */ return 0; - if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */ + if (index >= 46 && !(reg & 0x02)) /* PECI 1 */ return 0; return attr->mode; diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c index e1a907cae820..1e1cc67bcdea 100644 --- a/drivers/hwmon/oxp-sensors.c +++ b/drivers/hwmon/oxp-sensors.c @@ -220,6 +220,20 @@ static int tt_toggle_disable(void) } /* Callbacks for turbo toggle attribute */ +static umode_t tt_toggle_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + switch (board) { + case aok_zoe_a1: + case oxp_mini_amd_a07: + case oxp_mini_amd_pro: + return attr->mode; + default: + break; + } + return 0; +} + static ssize_t tt_toggle_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -396,7 +410,15 @@ static struct attribute *oxp_ec_attrs[] = { NULL }; -ATTRIBUTE_GROUPS(oxp_ec); +static struct attribute_group oxp_ec_attribute_group = { + .is_visible = tt_toggle_is_visible, + .attrs = oxp_ec_attrs, +}; + +static const struct attribute_group *oxp_ec_groups[] = { + &oxp_ec_attribute_group, + NULL +}; static const struct hwmon_ops oxp_ec_hwmon_ops = { .is_visible = oxp_ec_hwmon_is_visible, @@ -415,7 +437,6 @@ static int oxp_platform_probe(struct platform_device *pdev) const struct dmi_system_id *dmi_entry; struct device *dev = &pdev->dev; struct device *hwdev; - int ret; /* * Have to check for AMD processor here because DMI strings are the @@ -430,18 +451,6 @@ static int oxp_platform_probe(struct platform_device *pdev) board = (enum oxp_board)(unsigned long)dmi_entry->driver_data; - switch (board) { - case aok_zoe_a1: - case oxp_mini_amd_a07: - case oxp_mini_amd_pro: - ret = devm_device_add_groups(dev, oxp_ec_groups); - if (ret) - return ret; - break; - default: - break; - } - hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL, &oxp_ec_chip_info, NULL); @@ -451,6 +460,7 @@ static int oxp_platform_probe(struct platform_device *pdev) static struct platform_driver oxp_platform_driver = { .driver = { .name = "oxp-platform", + .dev_groups = oxp_ec_groups, }, .probe = oxp_platform_probe, }; diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index fa06325f5a7c..69a4e62b6c8d 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2745,9 +2745,8 @@ static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[] }, }; -static int _pmbus_is_enabled(struct device *dev, u8 page) +static int _pmbus_is_enabled(struct i2c_client *client, u8 page) { - struct i2c_client *client = to_i2c_client(dev->parent); int ret; ret = _pmbus_read_byte_data(client, page, PMBUS_OPERATION); @@ -2758,17 +2757,16 @@ static int _pmbus_is_enabled(struct device *dev, u8 page) return !!(ret & PB_OPERATION_CONTROL_ON); } -static int __maybe_unused pmbus_is_enabled(struct device *dev, u8 page) +static int __maybe_unused pmbus_is_enabled(struct i2c_client *client, u8 page) { - struct i2c_client *client = to_i2c_client(dev->parent); struct pmbus_data *data = i2c_get_clientdata(client); int ret; mutex_lock(&data->update_lock); - ret = _pmbus_is_enabled(dev, page); + ret = _pmbus_is_enabled(client, page); mutex_unlock(&data->update_lock); - return !!(ret & PB_OPERATION_CONTROL_ON); + return ret; } #define to_dev_attr(_dev_attr) \ @@ -2844,7 +2842,7 @@ static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flag if (status < 0) return status; - if (_pmbus_is_enabled(dev, page)) { + if (_pmbus_is_enabled(client, page)) { if (status & PB_STATUS_OFF) { *flags |= REGULATOR_ERROR_FAIL; *event |= REGULATOR_EVENT_FAIL; @@ -2898,7 +2896,10 @@ static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsi #if IS_ENABLED(CONFIG_REGULATOR) static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) { - return pmbus_is_enabled(rdev_get_dev(rdev), rdev_get_id(rdev)); + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + + return pmbus_is_enabled(client, rdev_get_id(rdev)); } static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) @@ -2945,6 +2946,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev) struct pmbus_data *data = i2c_get_clientdata(client); u8 page = rdev_get_id(rdev); int status, ret; + int event; mutex_lock(&data->update_lock); status = pmbus_get_status(client, page, PMBUS_STATUS_WORD); @@ -2964,7 +2966,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev) goto unlock; } - ret = pmbus_regulator_get_error_flags(rdev, &status); + ret = _pmbus_get_flags(data, rdev_get_id(rdev), &status, &event, false); if (ret) goto unlock; |