diff options
author | Guenter Roeck <linux@roeck-us.net> | 2022-05-20 11:47:21 -0700 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2022-07-13 08:38:17 -0700 |
commit | f30ce040a704f30f7ac6d3ec4c3f5390ccaabfe0 (patch) | |
tree | 75ad5c0e7dc39e441fd9d86feef946dacb10c60c /drivers/hwmon | |
parent | 88084a3df1672e131ddc1b4e39eeacfd39864acf (diff) | |
download | linux-f30ce040a704f30f7ac6d3ec4c3f5390ccaabfe0.tar.gz |
hwmon: (pmbus) Move pec attribute to I2C device
Enabling and disabling PEC for PMBus devices is currently only supported
with a debugfs attribute, which requires debugfs to be enabled and is
thus less than perfect. Take the lm90 driver as example and add a 'pec'
attribute to the I2C device if both the I2C adapter and the PMBus device
support it. Remove the now obsolete 'pec' attribute from debugfs.
Cc: Andrew Jeffery <andrew@aj.id.au>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 89 |
1 files changed, 50 insertions, 39 deletions
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 02912022853d..e670b868e74b 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2388,6 +2388,42 @@ static int pmbus_read_status_word(struct i2c_client *client, int page) return _pmbus_read_word_data(client, page, 0xff, PMBUS_STATUS_WORD); } +/* PEC attribute support */ + +static ssize_t pec_show(struct device *dev, struct device_attribute *dummy, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + + return sysfs_emit(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC)); +} + +static ssize_t pec_store(struct device *dev, struct device_attribute *dummy, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + bool enable; + int err; + + err = kstrtobool(buf, &enable); + if (err < 0) + return err; + + if (enable) + client->flags |= I2C_CLIENT_PEC; + else + client->flags &= ~I2C_CLIENT_PEC; + + return count; +} + +static DEVICE_ATTR_RW(pec); + +static void pmbus_remove_pec(void *dev) +{ + device_remove_file(dev, &dev_attr_pec); +} + static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, struct pmbus_driver_info *info) { @@ -2474,6 +2510,20 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, return ret; } + if (client->flags & I2C_CLIENT_PEC) { + /* + * If I2C_CLIENT_PEC is set here, both the I2C adapter and the + * chip support PEC. Add 'pec' attribute to client device to let + * the user control it. + */ + ret = device_create_file(dev, &dev_attr_pec); + if (ret) + return ret; + ret = devm_add_action_or_reset(dev, pmbus_remove_pec, dev); + if (ret) + return ret; + } + return 0; } @@ -2782,42 +2832,6 @@ static int pmbus_debugfs_get_status(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_status, pmbus_debugfs_get_status, NULL, "0x%04llx\n"); -static int pmbus_debugfs_get_pec(void *data, u64 *val) -{ - struct i2c_client *client = data; - - *val = !!(client->flags & I2C_CLIENT_PEC); - - return 0; -} - -static int pmbus_debugfs_set_pec(void *data, u64 val) -{ - int rc; - struct i2c_client *client = data; - - if (!val) { - client->flags &= ~I2C_CLIENT_PEC; - return 0; - } - - if (val != 1) - return -EINVAL; - - rc = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); - if (rc < 0) - return rc; - - if (!(rc & PB_CAPABILITY_ERROR_CHECK)) - return -EOPNOTSUPP; - - client->flags |= I2C_CLIENT_PEC; - - return 0; -} -DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_pec, pmbus_debugfs_get_pec, - pmbus_debugfs_set_pec, "%llu\n"); - static void pmbus_remove_debugfs(void *data) { struct dentry *entry = data; @@ -2853,9 +2867,6 @@ static int pmbus_init_debugfs(struct i2c_client *client, if (!entries) return -ENOMEM; - debugfs_create_file("pec", 0664, data->debugfs, client, - &pmbus_debugfs_ops_pec); - for (i = 0; i < data->info->pages; ++i) { /* Check accessibility of status register if it's not page 0 */ if (!i || pmbus_check_status_register(client, i)) { |