[PATCH 2/3] hwmon: pmbus: Add set_page() callback

Andrew Jeffery andrew at aj.id.au
Tue Sep 5 17:28:27 AEST 2017


With the improvement to error reporting in the PMBus core, issuing
CLEAR_FAULTS now propagates the error up the call chain where in the
past it was swallowed. This error propagation affects the 'virtual
pages' implemented in the max31785 driver: In some circumstances
pmbus_clear_faults() is issued unconditionally against a device.
pmbus_clear_faults() eventually calls pmbus_set_page(), which may issue
a PAGE command to the device. pmbus_set_page() issues
i2c_smbus_write_byte_data() directly, not routing through any of the
existing write path hooks, leaving the driver with no method to
intercept it.

As such, add a callback so we can intercept it.

Signed-off-by: Andrew Jeffery <andrew at aj.id.au>
---
 drivers/hwmon/pmbus/pmbus.h      |  1 +
 drivers/hwmon/pmbus/pmbus_core.c | 17 ++++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h
index f8d7a7e0dce0..ed15d3b92f76 100644
--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -394,6 +394,7 @@ struct pmbus_driver_info {
 	 * register does not exist, and that no attempt should be made to read
 	 * the standard register.
 	 */
+	int (*set_page)(struct i2c_client *client, int page);
 	int (*read_byte_data)(struct i2c_client *client, int page, int reg);
 	int (*read_word_data)(struct i2c_client *client, int page, int reg);
 	int (*write_word_data)(struct i2c_client *client, int page, int reg,
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index b71d214d1510..5411b0af363d 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -158,7 +158,7 @@ void pmbus_clear_cache(struct i2c_client *client)
 }
 EXPORT_SYMBOL_GPL(pmbus_clear_cache);
 
-int pmbus_set_page(struct i2c_client *client, u8 page)
+static int _pmbus_set_page(struct i2c_client *client, u8 page)
 {
 	struct pmbus_data *data = i2c_get_clientdata(client);
 	int rv = 0;
@@ -174,6 +174,21 @@ int pmbus_set_page(struct i2c_client *client, u8 page)
 	}
 	return rv;
 }
+
+int pmbus_set_page(struct i2c_client *client, u8 page)
+{
+	struct pmbus_data *data = i2c_get_clientdata(client);
+	const struct pmbus_driver_info *info = data->info;
+	int status;
+
+	if (info->set_page) {
+		status = info->set_page(client, page);
+		if (status != -ENODATA)
+			return status;
+	}
+
+	return _pmbus_set_page(client, page);
+}
 EXPORT_SYMBOL_GPL(pmbus_set_page);
 
 int pmbus_write_byte(struct i2c_client *client, int page, u8 value)
-- 
2.11.0



More information about the openbmc mailing list