Commit 2f4effd8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hwmon-for-v6.5-rc4' of...

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
parents c06f9091 e146503a
...@@ -1027,7 +1027,7 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, ...@@ -1027,7 +1027,7 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = aqc_percent_to_pwm(ret); *val = aqc_percent_to_pwm(*val);
break; break;
} }
break; break;
......
...@@ -77,6 +77,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); ...@@ -77,6 +77,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
#define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19) #define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19)
#define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16) #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 k10temp_data {
struct pci_dev *pdev; struct pci_dev *pdev;
void (*read_htcreg)(struct pci_dev *pdev, u32 *regval); void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
...@@ -86,6 +93,7 @@ struct k10temp_data { ...@@ -86,6 +93,7 @@ struct k10temp_data {
u32 show_temp; u32 show_temp;
bool is_zen; bool is_zen;
u32 ccd_offset; u32 ccd_offset;
bool disp_negative;
}; };
#define TCTL_BIT 0 #define TCTL_BIT 0
...@@ -204,12 +212,12 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, ...@@ -204,12 +212,12 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
switch (channel) { switch (channel) {
case 0: /* Tctl */ case 0: /* Tctl */
*val = get_raw_temp(data); *val = get_raw_temp(data);
if (*val < 0) if (*val < 0 && !data->disp_negative)
*val = 0; *val = 0;
break; break;
case 1: /* Tdie */ case 1: /* Tdie */
*val = get_raw_temp(data) - data->temp_offset; *val = get_raw_temp(data) - data->temp_offset;
if (*val < 0) if (*val < 0 && !data->disp_negative)
*val = 0; *val = 0;
break; break;
case 2 ... 13: /* Tccd{1-12} */ case 2 ... 13: /* Tccd{1-12} */
...@@ -405,6 +413,11 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -405,6 +413,11 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
data->pdev = pdev; data->pdev = pdev;
data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */ 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 && if (boot_cpu_data.x86 == 0x15 &&
((boot_cpu_data.x86_model & 0xf0) == 0x60 || ((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
(boot_cpu_data.x86_model & 0xf0) == 0x70)) { (boot_cpu_data.x86_model & 0xf0) == 0x70)) {
......
...@@ -955,14 +955,25 @@ static const u16 scale_in[15] = { ...@@ -955,14 +955,25 @@ static const u16 scale_in[15] = {
800, 800 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 */ /* TSI temperatures are in 8.3 format */
...@@ -1673,7 +1684,8 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -1673,7 +1684,8 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
if (IS_ERR(data)) if (IS_ERR(data))
return PTR_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 static ssize_t
...@@ -1691,7 +1703,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf, ...@@ -1691,7 +1703,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
if (err < 0) if (err < 0)
return err; return err;
mutex_lock(&data->update_lock); 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]); err = nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], data->in[nr][index]);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return err ? : count; return err ? : count;
...@@ -3462,6 +3474,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, ...@@ -3462,6 +3474,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
data->name = nct6775_device_names[data->kind]; data->name = nct6775_device_names[data->kind];
data->bank = 0xff; /* Force initial bank selection */ data->bank = 0xff; /* Force initial bank selection */
data->scale_in = scale_in;
switch (data->kind) { switch (data->kind) {
case nct6106: case nct6106:
...@@ -3977,6 +3990,9 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, ...@@ -3977,6 +3990,9 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data,
break; break;
} }
if (data->kind == nct6798 || data->kind == nct6799)
data->scale_in = scale_in_6798;
reg_temp = NCT6779_REG_TEMP; reg_temp = NCT6779_REG_TEMP;
num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
if (data->kind == nct6791) { if (data->kind == nct6791) {
......
...@@ -586,7 +586,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio ...@@ -586,7 +586,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio
int creb; int creb;
int cred; 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); sio_data->sio_select(sio_data, NCT6775_LD_12);
cre0 = sio_data->sio_inb(sio_data, 0xe0); cre0 = sio_data->sio_inb(sio_data, 0xe0);
......
...@@ -98,6 +98,7 @@ struct nct6775_data { ...@@ -98,6 +98,7 @@ struct nct6775_data {
u8 bank; /* current register bank */ u8 bank; /* current register bank */
u8 in_num; /* number of in inputs we have */ u8 in_num; /* number of in inputs we have */
u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */
const u16 *scale_in; /* internal scaling factors */
unsigned int rpm[NUM_FAN]; unsigned int rpm[NUM_FAN];
u16 fan_min[NUM_FAN]; u16 fan_min[NUM_FAN];
u8 fan_pulses[NUM_FAN]; u8 fan_pulses[NUM_FAN];
......
...@@ -725,7 +725,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj, ...@@ -725,7 +725,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj,
if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */ if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */
return 0; return 0;
if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */ if (index >= 46 && !(reg & 0x02)) /* PECI 1 */
return 0; return 0;
return attr->mode; return attr->mode;
......
...@@ -220,6 +220,20 @@ static int tt_toggle_disable(void) ...@@ -220,6 +220,20 @@ static int tt_toggle_disable(void)
} }
/* Callbacks for turbo toggle attribute */ /* 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, static ssize_t tt_toggle_store(struct device *dev,
struct device_attribute *attr, const char *buf, struct device_attribute *attr, const char *buf,
size_t count) size_t count)
...@@ -396,7 +410,15 @@ static struct attribute *oxp_ec_attrs[] = { ...@@ -396,7 +410,15 @@ static struct attribute *oxp_ec_attrs[] = {
NULL 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 = { static const struct hwmon_ops oxp_ec_hwmon_ops = {
.is_visible = oxp_ec_hwmon_is_visible, .is_visible = oxp_ec_hwmon_is_visible,
...@@ -415,7 +437,6 @@ static int oxp_platform_probe(struct platform_device *pdev) ...@@ -415,7 +437,6 @@ static int oxp_platform_probe(struct platform_device *pdev)
const struct dmi_system_id *dmi_entry; const struct dmi_system_id *dmi_entry;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device *hwdev; struct device *hwdev;
int ret;
/* /*
* Have to check for AMD processor here because DMI strings are the * 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) ...@@ -430,18 +451,6 @@ static int oxp_platform_probe(struct platform_device *pdev)
board = (enum oxp_board)(unsigned long)dmi_entry->driver_data; 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, hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL,
&oxp_ec_chip_info, NULL); &oxp_ec_chip_info, NULL);
...@@ -451,6 +460,7 @@ static int oxp_platform_probe(struct platform_device *pdev) ...@@ -451,6 +460,7 @@ static int oxp_platform_probe(struct platform_device *pdev)
static struct platform_driver oxp_platform_driver = { static struct platform_driver oxp_platform_driver = {
.driver = { .driver = {
.name = "oxp-platform", .name = "oxp-platform",
.dev_groups = oxp_ec_groups,
}, },
.probe = oxp_platform_probe, .probe = oxp_platform_probe,
}; };
......
...@@ -2745,9 +2745,8 @@ static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[] ...@@ -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; int ret;
ret = _pmbus_read_byte_data(client, page, PMBUS_OPERATION); ret = _pmbus_read_byte_data(client, page, PMBUS_OPERATION);
...@@ -2758,17 +2757,16 @@ static int _pmbus_is_enabled(struct device *dev, u8 page) ...@@ -2758,17 +2757,16 @@ static int _pmbus_is_enabled(struct device *dev, u8 page)
return !!(ret & PB_OPERATION_CONTROL_ON); 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); struct pmbus_data *data = i2c_get_clientdata(client);
int ret; int ret;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
ret = _pmbus_is_enabled(dev, page); ret = _pmbus_is_enabled(client, page);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return !!(ret & PB_OPERATION_CONTROL_ON); return ret;
} }
#define to_dev_attr(_dev_attr) \ #define to_dev_attr(_dev_attr) \
...@@ -2844,7 +2842,7 @@ static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flag ...@@ -2844,7 +2842,7 @@ static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flag
if (status < 0) if (status < 0)
return status; return status;
if (_pmbus_is_enabled(dev, page)) { if (_pmbus_is_enabled(client, page)) {
if (status & PB_STATUS_OFF) { if (status & PB_STATUS_OFF) {
*flags |= REGULATOR_ERROR_FAIL; *flags |= REGULATOR_ERROR_FAIL;
*event |= REGULATOR_EVENT_FAIL; *event |= REGULATOR_EVENT_FAIL;
...@@ -2898,7 +2896,10 @@ static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsi ...@@ -2898,7 +2896,10 @@ static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsi
#if IS_ENABLED(CONFIG_REGULATOR) #if IS_ENABLED(CONFIG_REGULATOR)
static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) 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) 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) ...@@ -2945,6 +2946,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev)
struct pmbus_data *data = i2c_get_clientdata(client); struct pmbus_data *data = i2c_get_clientdata(client);
u8 page = rdev_get_id(rdev); u8 page = rdev_get_id(rdev);
int status, ret; int status, ret;
int event;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
status = pmbus_get_status(client, page, PMBUS_STATUS_WORD); status = pmbus_get_status(client, page, PMBUS_STATUS_WORD);
...@@ -2964,7 +2966,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev) ...@@ -2964,7 +2966,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev)
goto unlock; goto unlock;
} }
ret = pmbus_regulator_get_error_flags(rdev, &status); ret = _pmbus_get_flags(data, rdev_get_id(rdev), &status, &event, false);
if (ret) if (ret)
goto unlock; goto unlock;
......
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