[PATCH 3/5] hwmon: (pmbus/mp9945) Replace raw I2C calls with PMBus core API

From: Pradhan, Sanman

Date: Mon Mar 23 2026 - 12:50:02 EST


From: Sanman Pradhan <psanman@xxxxxxxxxxx>

The mp9945 read_byte_data, read_word_data, and mp9945_read_vout
callbacks use raw i2c_smbus_write_byte_data() to set PMBUS_PAGE and
raw i2c_smbus_read_word_data() to read registers. These raw page
writes desynchronize the PMBus core's internal page cache: after a raw
write to PMBUS_PAGE, the core still believes the previous page is
selected and may skip the page-select on the next pmbus_read_word_data()
call, causing reads from the wrong page. As a secondary benefit,
switching to the core helpers also routes all post-probe accesses
through the update_lock mutex, closing a potential race with concurrent
sysfs reads.

Replace the raw I2C calls with pmbus_read_word_data(), which handles
page selection, page cache coherency, and locking internally. Remove
the now-unnecessary manual PMBUS_PAGE writes from read_byte_data and
read_word_data. The identify() function retains raw I2C because it
runs during probe before pmbus_do_probe() registers the device.

Fixes: 6923e2827d58 ("hwmon: (pmbus) add driver for MPS MP9945")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Sanman Pradhan <psanman@xxxxxxxxxxx>
---
drivers/hwmon/pmbus/mp9945.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/hwmon/pmbus/mp9945.c b/drivers/hwmon/pmbus/mp9945.c
index 34822e0de812..1723ef84eb0c 100644
--- a/drivers/hwmon/pmbus/mp9945.c
+++ b/drivers/hwmon/pmbus/mp9945.c
@@ -43,11 +43,12 @@ struct mp9945_data {

#define to_mp9945_data(x) container_of(x, struct mp9945_data, info)

-static int mp9945_read_vout(struct i2c_client *client, struct mp9945_data *data)
+static int mp9945_read_vout(struct i2c_client *client, struct mp9945_data *data,
+ int page, int phase)
{
int ret;

- ret = i2c_smbus_read_word_data(client, PMBUS_READ_VOUT);
+ ret = pmbus_read_word_data(client, page, phase, PMBUS_READ_VOUT);
if (ret < 0)
return ret;

@@ -73,12 +74,6 @@ static int mp9945_read_vout(struct i2c_client *client, struct mp9945_data *data)

static int mp9945_read_byte_data(struct i2c_client *client, int page, int reg)
{
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
- if (ret < 0)
- return ret;
-
switch (reg) {
case PMBUS_VOUT_MODE:
/*
@@ -98,17 +93,13 @@ static int mp9945_read_word_data(struct i2c_client *client, int page, int phase,
struct mp9945_data *data = to_mp9945_data(info);
int ret;

- ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
- if (ret < 0)
- return ret;
-
switch (reg) {
case PMBUS_READ_VOUT:
- ret = mp9945_read_vout(client, data);
+ ret = mp9945_read_vout(client, data, page, phase);
break;
case PMBUS_VOUT_OV_FAULT_LIMIT:
case PMBUS_VOUT_UV_FAULT_LIMIT:
- ret = i2c_smbus_read_word_data(client, reg);
+ ret = pmbus_read_word_data(client, page, phase, reg);
if (ret < 0)
return ret;

@@ -116,7 +107,7 @@ static int mp9945_read_word_data(struct i2c_client *client, int page, int phase,
ret = DIV_ROUND_CLOSEST((ret & GENMASK(11, 0)) * 39, 20);
break;
case PMBUS_VOUT_UV_WARN_LIMIT:
- ret = i2c_smbus_read_word_data(client, reg);
+ ret = pmbus_read_word_data(client, page, phase, reg);
if (ret < 0)
return ret;

--
2.34.1