From 044cd3a574be5cd97ab80d0c6d06f5fab327541d Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 29 Jul 2011 22:08:07 -0700 Subject: hwmon: (pmbus) Virtualize pmbus_write_byte With virtual pages and to be able to handle more chips, it is necessary to virtualise pmbus_write_byte(). Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson --- drivers/hwmon/pmbus/pmbus.h | 1 + drivers/hwmon/pmbus/pmbus_core.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h index 0808d986d75b..a6ae20ffef6b 100644 --- a/drivers/hwmon/pmbus/pmbus.h +++ b/drivers/hwmon/pmbus/pmbus.h @@ -325,6 +325,7 @@ struct pmbus_driver_info { int (*read_word_data)(struct i2c_client *client, int page, int reg); int (*write_word_data)(struct i2c_client *client, int page, int reg, u16 word); + int (*write_byte)(struct i2c_client *client, int page, u8 value); /* * The identify function determines supported PMBus functionality. * This function is only necessary if a chip driver supports multiple diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 5c1b6cf31701..a561c3a0e916 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -182,6 +182,24 @@ int pmbus_write_byte(struct i2c_client *client, int page, u8 value) } EXPORT_SYMBOL_GPL(pmbus_write_byte); +/* + * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if + * a device specific mapping funcion exists and calls it if necessary. + */ +static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) +{ + struct pmbus_data *data = i2c_get_clientdata(client); + const struct pmbus_driver_info *info = data->info; + int status; + + if (info->write_byte) { + status = info->write_byte(client, page, value); + if (status != -ENODATA) + return status; + } + return pmbus_write_byte(client, page, value); +} + int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word) { int rv; @@ -281,7 +299,7 @@ static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) static void pmbus_clear_fault_page(struct i2c_client *client, int page) { - pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); + _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); } void pmbus_clear_faults(struct i2c_client *client) -- cgit From 3a2805e845761ea76a6ad5688d637b2624de0cab Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 29 Jul 2011 23:05:25 -0700 Subject: hwmon: (pmbus/lm25066) Ignore byte writes to non-zero pages pmbus_clear_faults() attempts to clear faults on non-existing real pages. As a result, the command error bit in the status register is set, and faults are not really cleared. All byte writes to non-zero pages are requests to clear the status register on that page. Since non-zero pages are virtual and do not exist on the chip, there is nothing to do, and such requests have to be ignored. This fixes above problem. Signed-off-by: Guenter Roeck Reviewed-by: Robert Coulson --- drivers/hwmon/pmbus/lm25066.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index d4bc114572de..ac254fba551b 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -161,6 +161,17 @@ static int lm25066_write_word_data(struct i2c_client *client, int page, int reg, return ret; } +static int lm25066_write_byte(struct i2c_client *client, int page, u8 value) +{ + if (page > 1) + return -EINVAL; + + if (page == 0) + return pmbus_write_byte(client, 0, value); + + return 0; +} + static int lm25066_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -204,6 +215,7 @@ static int lm25066_probe(struct i2c_client *client, info->read_word_data = lm25066_read_word_data; info->write_word_data = lm25066_write_word_data; + info->write_byte = lm25066_write_byte; switch (id->driver_data) { case lm25066: -- cgit From 66a89b2164e2d30661edbd1953eacf0594d8203a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 9 Aug 2011 11:10:56 -0400 Subject: hwmon: (ibmaem) add missing kfree rs_resp is dynamically allocated in aem_read_sensor(), so it should be freed before exiting in every case. This collects the kfree and the return at the end of the function. Signed-off-by: Julia Lawall Signed-off-by: Guenter Roeck Cc: stable@kernel.org # 2.6.27+ --- drivers/hwmon/ibmaem.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 1a409c5bc9bc..c316294c48b4 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -432,13 +432,15 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, aem_send_message(ipmi); res = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!res) - return -ETIMEDOUT; + if (!res) { + res = -ETIMEDOUT; + goto out; + } if (ipmi->rx_result || ipmi->rx_msg_len != rs_size || memcmp(&rs_resp->id, &system_x_id, sizeof(system_x_id))) { - kfree(rs_resp); - return -ENOENT; + res = -ENOENT; + goto out; } switch (size) { @@ -463,8 +465,11 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, break; } } + res = 0; - return 0; +out: + kfree(rs_resp); + return res; } /* Update AEM energy registers */ -- cgit