From: Guenter Roeck <linux@roeck-us.net>
To: Hardware Monitoring <linux-hwmon@vger.kernel.org>
Cc: Sanman Pradhan <psanman@juniper.net>, Guenter Roeck <linux@roeck-us.net>
Subject: [PATCH 2/5] hwmon: (pmbus) Introduce the concept of "write-only" attributes
Date: Wed, 25 Mar 2026 11:16:28 -0700 [thread overview]
Message-ID: <20260325181631.17259-3-linux@roeck-us.net> (raw)
In-Reply-To: <20260325181631.17259-1-linux@roeck-us.net>
Attributes intended to clear sensor history are intended to be writeable
only. Reading those attributes today results in reporting more or less
random values. To avoid ABI surprises, have those attributes explicitly
return 0 when reading.
Fixes: 787c095edaa9d ("hwmon: (pmbus/core) Add support for rated attributes")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
drivers/hwmon/pmbus/pmbus_core.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index ecd1dddcbe0f..cbc36f0ba4bf 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1209,6 +1209,12 @@ static ssize_t pmbus_show_boolean(struct device *dev,
return sysfs_emit(buf, "%d\n", val);
}
+static ssize_t pmbus_show_zero(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ return sysfs_emit(buf, "0\n");
+}
+
static ssize_t pmbus_show_sensor(struct device *dev,
struct device_attribute *devattr, char *buf)
{
@@ -1407,7 +1413,7 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
int reg,
enum pmbus_sensor_classes class,
bool update, bool readonly,
- bool convert)
+ bool writeonly, bool convert)
{
struct pmbus_sensor *sensor;
struct device_attribute *a;
@@ -1436,7 +1442,8 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
sensor->data = -ENODATA;
pmbus_dev_attr_init(a, sensor->name,
readonly ? 0444 : 0644,
- pmbus_show_sensor, pmbus_set_sensor);
+ writeonly ? pmbus_show_zero : pmbus_show_sensor,
+ pmbus_set_sensor);
if (pmbus_add_attribute(data, &a->attr))
return NULL;
@@ -1496,6 +1503,7 @@ struct pmbus_limit_attr {
u16 reg; /* Limit register */
u16 sbit; /* Alarm attribute status bit */
bool readonly:1; /* True if the attribute is read-only */
+ bool writeonly:1; /* True if the attribute is write-only */
bool update:1; /* True if register needs updates */
bool low:1; /* True if low limit; for limits with compare functions only */
const char *attr; /* Attribute name */
@@ -1545,7 +1553,7 @@ static int pmbus_add_limit_attrs(struct i2c_client *client,
curr = pmbus_add_sensor(data, name, l->attr, index,
page, 0xff, l->reg, attr->class,
attr->update || l->update,
- l->readonly, true);
+ l->readonly, l->writeonly, true);
if (!curr)
return -ENOMEM;
if (l->sbit && (info->func[page] & attr->sfunc)) {
@@ -1585,7 +1593,7 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
return ret;
}
base = pmbus_add_sensor(data, name, "input", index, page, phase,
- attr->reg, attr->class, true, true, true);
+ attr->reg, attr->class, true, true, false, true);
if (!base)
return -ENOMEM;
/* No limit and alarm attributes for phase specific sensors */
@@ -1722,6 +1730,7 @@ static const struct pmbus_limit_attr vin_limit_attrs[] = {
.attr = "highest",
}, {
.reg = PMBUS_VIRT_RESET_VIN_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_VIN_MIN,
@@ -1796,6 +1805,7 @@ static const struct pmbus_limit_attr vout_limit_attrs[] = {
.attr = "highest",
}, {
.reg = PMBUS_VIRT_RESET_VOUT_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_VOUT_MIN,
@@ -1877,6 +1887,7 @@ static const struct pmbus_limit_attr iin_limit_attrs[] = {
.attr = "highest",
}, {
.reg = PMBUS_VIRT_RESET_IIN_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_IIN_MAX,
@@ -1918,6 +1929,7 @@ static const struct pmbus_limit_attr iout_limit_attrs[] = {
.attr = "highest",
}, {
.reg = PMBUS_VIRT_RESET_IOUT_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_IOUT_MAX,
@@ -1976,6 +1988,7 @@ static const struct pmbus_limit_attr pin_limit_attrs[] = {
.attr = "input_highest",
}, {
.reg = PMBUS_VIRT_RESET_PIN_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_PIN_MAX,
@@ -2017,6 +2030,7 @@ static const struct pmbus_limit_attr pout_limit_attrs[] = {
.attr = "input_highest",
}, {
.reg = PMBUS_VIRT_RESET_POUT_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_POUT_MAX,
@@ -2088,6 +2102,7 @@ static const struct pmbus_limit_attr temp_limit_attrs[] = {
.attr = "highest",
}, {
.reg = PMBUS_VIRT_RESET_TEMP_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_MAX_TEMP_1,
@@ -2133,6 +2148,7 @@ static const struct pmbus_limit_attr temp_limit_attrs2[] = {
.attr = "highest",
}, {
.reg = PMBUS_VIRT_RESET_TEMP2_HISTORY,
+ .writeonly = true,
.attr = "reset_history",
}, {
.reg = PMBUS_MFR_MAX_TEMP_2,
@@ -2250,7 +2266,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
sensor = pmbus_add_sensor(data, "fan", "target", index, page,
0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN,
- false, false, true);
+ false, false, false, true);
if (!sensor)
return -ENOMEM;
@@ -2261,14 +2277,14 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
sensor = pmbus_add_sensor(data, "pwm", NULL, index, page,
0xff, PMBUS_VIRT_PWM_1 + id, PSC_PWM,
- false, false, true);
+ false, false, false, true);
if (!sensor)
return -ENOMEM;
sensor = pmbus_add_sensor(data, "pwm", "enable", index, page,
0xff, PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM,
- true, false, false);
+ true, false, false, false);
if (!sensor)
return -ENOMEM;
@@ -2310,7 +2326,7 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
if (pmbus_add_sensor(data, "fan", "input", index,
page, 0xff, pmbus_fan_registers[f],
- PSC_FAN, true, true, true) == NULL)
+ PSC_FAN, true, true, false, true) == NULL)
return -ENOMEM;
/* Fan control */
--
2.45.2
next prev parent reply other threads:[~2026-03-25 18:16 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-25 18:16 [PATCH 0/5] hwmon: (pmbus) PMBus fixes and improvements Guenter Roeck
2026-03-25 18:16 ` [PATCH 1/5] hwmon: (pmbus) Mark lowest/average/highest/rated attributes as read-only Guenter Roeck
2026-03-25 18:16 ` Guenter Roeck [this message]
2026-03-25 18:16 ` [PATCH 3/5] hwmon: (pmbus/core) Protect regulator operations with mutex Guenter Roeck
2026-03-25 19:05 ` Pradhan, Sanman
2026-03-25 20:02 ` Guenter Roeck
2026-03-25 18:16 ` [PATCH 4/5] hwmon: (pmbus) Add support for guarded PMBus lock Guenter Roeck
2026-03-25 18:16 ` [PATCH 5/5] hwmon: (pmbus_core) Use guard() for mutex protection Guenter Roeck
2026-03-25 20:25 ` [PATCH 0/5] hwmon: (pmbus) PMBus fixes and improvements Pradhan, Sanman
2026-03-25 20:31 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260325181631.17259-3-linux@roeck-us.net \
--to=linux@roeck-us.net \
--cc=linux-hwmon@vger.kernel.org \
--cc=psanman@juniper.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox