aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2011-07-09 15:06:45 -0400
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-07-28 20:02:40 -0400
commitc6bfb767e431d3a236eab439d3660ff562598c84 (patch)
tree069f5ce348f55a0eea1e58c224a51760e323a135 /drivers/hwmon
parent9c1ed8941d30fd6252e84a9941e6507e497d242b (diff)
hwmon: (pmbus) Strengthen check for status register existence
With virtual register page support, it is now possible that the status register on virtual pages does not exist or is itself virtual. To take this into account when creating alarm attributes, generate those attributes only if the status register on the respective page is known to exist. Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com> Reviewed-by: Robert Coulson <robert.coulson@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/pmbus/pmbus_core.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 50634497db8d..df3971f6414c 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -254,6 +254,24 @@ int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg)
254} 254}
255EXPORT_SYMBOL_GPL(pmbus_read_byte_data); 255EXPORT_SYMBOL_GPL(pmbus_read_byte_data);
256 256
257/*
258 * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if
259 * a device specific mapping function exists and calls it if necessary.
260 */
261static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg)
262{
263 struct pmbus_data *data = i2c_get_clientdata(client);
264 const struct pmbus_driver_info *info = data->info;
265 int status;
266
267 if (info->read_byte_data) {
268 status = info->read_byte_data(client, page, reg);
269 if (status != -ENODATA)
270 return status;
271 }
272 return pmbus_read_byte_data(client, page, reg);
273}
274
257static void pmbus_clear_fault_page(struct i2c_client *client, int page) 275static void pmbus_clear_fault_page(struct i2c_client *client, int page)
258{ 276{
259 pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); 277 pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS);
@@ -287,7 +305,7 @@ bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg)
287 int rv; 305 int rv;
288 struct pmbus_data *data = i2c_get_clientdata(client); 306 struct pmbus_data *data = i2c_get_clientdata(client);
289 307
290 rv = pmbus_read_byte_data(client, page, reg); 308 rv = _pmbus_read_byte_data(client, page, reg);
291 if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) 309 if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK))
292 rv = pmbus_check_status_cml(client); 310 rv = pmbus_check_status_cml(client);
293 pmbus_clear_fault_page(client, -1); 311 pmbus_clear_fault_page(client, -1);
@@ -316,24 +334,6 @@ const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client)
316} 334}
317EXPORT_SYMBOL_GPL(pmbus_get_driver_info); 335EXPORT_SYMBOL_GPL(pmbus_get_driver_info);
318 336
319/*
320 * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if
321 * a device specific mapping function exists and calls it if necessary.
322 */
323static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg)
324{
325 struct pmbus_data *data = i2c_get_clientdata(client);
326 const struct pmbus_driver_info *info = data->info;
327 int status;
328
329 if (info->read_byte_data) {
330 status = info->read_byte_data(client, page, reg);
331 if (status != -ENODATA)
332 return status;
333 }
334 return pmbus_read_byte_data(client, page, reg);
335}
336
337static struct pmbus_data *pmbus_update_device(struct device *dev) 337static struct pmbus_data *pmbus_update_device(struct device *dev)
338{ 338{
339 struct i2c_client *client = to_i2c_client(dev); 339 struct i2c_client *client = to_i2c_client(dev);
@@ -1037,9 +1037,11 @@ static void pmbus_add_sensor_attrs_one(struct i2c_client *client,
1037 index, page, cbase, attr); 1037 index, page, cbase, attr);
1038 /* 1038 /*
1039 * Add generic alarm attribute only if there are no individual 1039 * Add generic alarm attribute only if there are no individual
1040 * alarm attributes, and if there is a global alarm bit. 1040 * alarm attributes, if there is a global alarm bit, and if
1041 * the generic status register for this page is accessible.
1041 */ 1042 */
1042 if (!have_alarm && attr->gbit) 1043 if (!have_alarm && attr->gbit &&
1044 pmbus_check_byte_register(client, page, PMBUS_STATUS_BYTE))
1043 pmbus_add_boolean_reg(data, name, "alarm", index, 1045 pmbus_add_boolean_reg(data, name, "alarm", index,
1044 PB_STATUS_BASE + page, 1046 PB_STATUS_BASE + page,
1045 attr->gbit); 1047 attr->gbit);